在 Maybe 中操作一个值

Manipulating a value in a Maybe

我正在编写的一些代码中的一个函数returns

Just 3

我想要的是删除 Just 并随意操作 3。

我必须承认我不理解 Just 语法,但是在我解决这个问题的同时,我将不胜感激。

Just 3 的类型为 Maybe Int。您可以在 Maybe 中操作 int ,最简单的形式是 fmap,例如

ghci> fmap (\x -> x + 1) (Just 3) 
Just 4

保留了Maybe类型的结构,也就是说保留了Nothings

ghci> fmap (\x -> x + 1) Nothing
Nothing

或者你可以定义一个模式匹配的函数:

doThing :: Maybe Int -> String
doThing (Just x) = "I got " ++ show x
doThing Nothing  = "I didn't get anything"

ghci> doThing (Just 3)
"I got 3"

还有一个有用的函数叫做fromMaybe(在Data.Maybe中定义):

fromMaybe :: a -> Maybe a -> a

它将从 Maybe 中提取值,但是如果结果是 Nothing,您必须向它提供要 return 的值:

ghci> import Data.Maybe (fromMaybe)
ghci> fromMaybe 0 (Just 3)
3
ghci> fromMaybe 0 Nothing
0

请注意,在所有这些情况下,如果值为 Nothing,我们必须决定要做什么,这是 Maybe 类型的基本特征。

如果我给你一份巧克力蛋糕的食谱,你就不能拿掉食谱,随便吃蛋糕。您首先必须按照食谱进行操作。

同样,如果我给你一个Maybe Int,你不能只把Maybe拿下来,然后去操纵Int;你必须首先检查它,看看你是否有 Just 一个你可以操纵的 IntNothing.

所有其他技术都使用的执行此检查的最基本方法是模式匹配。 luqui 建议的 fromMaybe 函数就是一个很好的例子。如果找到 Nothing.

,它将使用给定的默认值将 Maybe a 转换为 a
fromMaybe :: a -> Maybe a -> a
fromMaybe def (Just val) = val
fromMaybe def Nothing = def

专业提示:在学习的过程中Haskell,您会发现几个很好的机会来回想蛋糕的寓言。

另一个可能有用的函数,实际上在 Prelude 中,是

maybe :: b -> (a -> b) -> Maybe a -> b

fromMaybe 非常相似,但允许您使用函数来处理 Just 中的变量(您需要提供与输出类型相匹配的默认值如果你有Nothing)的函数。示例:

maybeShow = maybe "Got nothing..." show

maybeShow $ Just 3  -- gives "3"
maybeShow $ Nothing -- gives "Got nothing..."

然后还有一个功能,其他回答者似乎在战略上避免了 :) 但我认为为了完整性应该放在这里:

import Data.Maybe (fromJust)
fromJust :: Maybe a -> a

从其 Just 包装器中获取一个值。这个函数的问题是它是一个部分函数,​​即它没有为 Nothing 值定义:

fromJust $ Just 3  -- gives 3
fromJust $ Nothing -- gives *** Exception: Maybe.fromJust: Nothing

如您所见,使用此功能存在一定风险,而且绝对不是一个干净的解决方案。不过,如果您 确定 不会得到 Nothing,或者如果您只是玩玩并且想摆脱烦人的 Maybe,它在实践中非常有用。