【问题标题】:Get Index of Num Array in Haskell在 Haskell 中获取 Num 数组的索引
【发布时间】:2026-02-08 11:20:15
【问题描述】:

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

【问题讨论】:

  • 如果元素不在列表中,你想返回什么?

标签: list haskell indexing


【解决方案1】:

原理

安全地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

因此,它采用b 类型的“默认值”和从ab 的函数,并将返回b。这是否是默认值取决于Maybe a 值是否存在或者是Nothing。例如,如果您想检查列表元素是否允许进入 18+ 俱乐部,您可以这样做

maybe False (\n -> n >= 18) (elemIndex 'C' list)

如果索引小于 18,则返回 False,如果元素不存在于列表中。如果确实存在,它会检查它是否大于等于18,然后返回True。

保留Just

到目前为止我已经告诉你的是如何以安全的方式摆脱Just。有时,你还不能摆脱Just——有时你没有合理的价值来返回如果你手上有一个Nothing而不是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 时元素都会出现在列表中的某个位置,那么可以使用fromJustfromJust 会盲目地尝试从 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 函数。

【讨论】:

    【解决方案2】:

    使用Data.Maybe 中的fromJust。喜欢:

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

    你只会得到1

    但是,如果列表中没有所需的元素,这将失败,并且会出现异常:

    *** Exception: Maybe.fromJust: Nothing
    

    【讨论】:

    • 使用fromJust,前提是您可以证明您要查找的元素存在于列表中。在任何其他情况下,Haskell 都具有出色的工具来操作 Maybe 值内的东西——所以你可以保留 Just 直到你确定你可以安全地删除它并仍然返回一个合理的值。
    • 这对我很有用。我正在搜索的元素肯定在列表中,所以我不会收到错误消息。非常感谢
    • 即使在这种情况下,您也应该使用fromMaybe,它允许您指定默认情况(代表Nothing)并在其中放置一个精确的错误,以便您查明问题的根源如果你错了,因为默认的错误信息不会有太大帮助......所以像fromMaybe (error "Impossible ! The element should be in the list in this function _fun_") $ elemIndex...