0

我需要在类型数组中获取元素的位置Array Int Int。我找到了方法elemIndexfind获得职位。我的问题是,例如,我不需要前缀Just 5。那么我如何只获得5示例中的数字?

4

2 回答 2

7

原则

安全地从值中提取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 ato的函数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,而不关心如果那里没有会发生什么JustfromJust如果出现问题,只会爆炸您的程序(抛出异常)。

如您所知,您必须非常小心地使用它。

风格不安全

但是,正如 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函数。

于 2013-11-03T14:28:56.273 回答
3

使用fromJustData.Maybe. 喜欢:

fromJust $ elemIndex 2 [1,2,3,4,5]

而你只会得到1.

但是,如果您在列表中没有所需的元素,这将失败,并且您会得到一个异常:

*** Exception: Maybe.fromJust: Nothing
于 2013-11-03T14:04:04.170 回答