我需要在类型数组中获取元素的位置Array Int Int
。我找到了方法elemIndex
或find
获得职位。我的问题是,例如,我不需要前缀Just 5
。那么我如何只获得5
示例中的数字?
2 回答
原则
要安全地从值中提取Maybe a
值,您可以使用模式匹配,如下所示:
case elemIndex 'C' list of
Just n -> "You can find C at position " ++ show n
Nothing -> "There is no C in the list."
这将返回类似
"You can find C at position 2"
或者
"There is no C in the list."
取决于列表中是否有 C。
让它方便
当然,这种模式匹配一直都很难写,所以有一个函数maybe
可以做几乎相同的事情。如果您查看它的类型签名,您会看到
maybe :: b -> (a -> b) -> Maybe a -> b
所以它需要一个 type 的“默认值”b
和一个 from a
to的函数b
,并将返回一个b
. 这是否是默认值取决于该Maybe a
值是否存在Nothing
。例如,如果你想检查一个列表元素是否允许进入 18+ 俱乐部,你可以这样做
maybe False (\n -> n >= 18) (elemIndex 'C' list)
如果索引小于 18或列表中不存在该元素,这将显示 False。如果确实存在,它将检查它是否大于或等于 18,然后返回 True。
保持Just
到目前为止,我告诉你的是如何以Just
安全的方式摆脱它。有时,你还不能摆脱Just
刚刚——有时,如果你手上有 aNothing
而不是Just
. 然后,您可以做的是在值仍在Just
. 例如,要从 just 中的值中减去 15,只需执行
fmap (subtract 15) (Just 23)
这将返回
Just 8
所以你会看到如何fmap
获取一个Just something
值并将函数应用于something
它的一部分,保持Just
外部。如果你愿意
fmap (subtract 15) Nothing
它只会保留Nothing
,所以结果是
Nothing
让它变得不安全(孩子们,不要在家里尝试这个!)
Maybe
很棒,因为它是一个错误处理系统,可以迫使你做正确的事。您不能忽略错误的可能性(由Nothing
. 表示)。另一个常见的错误处理系统对此很糟糕。该系统是例外系统。没有人会知道您是否公然忽略可能发生的异常,这是非常不安全的程序的基础。
所以你真的想保留它,Just
直到你可以把它扔掉,同时Nothing
用合理的东西替换一个潜在的价值。
如果你能保证没有价值的可能性Nothing
。如果您确定每次调用elemIndex
该元素时都会出现在 list 中的某个位置,那么可以使用fromJust
. fromJust
会盲目地尝试从 a 中获取一个值Just
,而不关心如果那里没有会发生什么Just
。fromJust
如果出现问题,只会爆炸您的程序(抛出异常)。
如您所知,您必须非常小心地使用它。
风格不安全
但是,正如 Jedai 在评论中指出的那样,即使您无法获得Nothing
价值,也最好明确说明。而不是使用fromJust
,考虑做类似的事情
fromMaybe (error "The input " ++ show list ++ " shouldn't create a Nothing value!")
(elemIndex 'C' list)
这将引发一个非常具体的错误消息,指出一定是哪里出了问题。
这当然与看起来像的模式匹配相同
case elemIndex 'C' list of
Just n -> n
Nothing -> error "The input " ++ show list ++ " shouldn't create a Nothing value!"
只压缩成标准fromMaybe
函数。
使用fromJust
从Data.Maybe
. 喜欢:
fromJust $ elemIndex 2 [1,2,3,4,5]
而你只会得到1
.
但是,如果您在列表中没有所需的元素,这将失败,并且您会得到一个异常:
*** Exception: Maybe.fromJust: Nothing