Haskell - 如何获取列表中元素的索引?

Haskell - How to get index of elem in list?

我想获取列表中元素的索引?不是可能 Int,只有 int.

>elemIndex 'f' "BarFoof"
>Just 6

但需要6个

您可以使用 fromMaybe :: a -> Maybe a -> a 解包 Just 的值,并进一步添加默认值,以防它是 Nothing.

所以你可以实现一个功能:

import Data.Maybe(<b>fromMaybe</b>)

elemIndex' :: Eq a => a -> [a] -> Int
elemIndex' x = <b>fromMaybe (-1)</b> . elemIndex x

这里会 return -1 以防找不到元素。例如:

Prelude Data.Maybe Data.List> elemIndex' 'f' "BarFoof"
6
Prelude Data.Maybe Data.List> elemIndex' 'q' "BarFoof"
-1

也就是说,在 Haskell 中,Maybe 通常用于表示可能 "fail" 的计算,这样如果您 post 处理结果,您还将考虑 Nothing(列表中未找到的元素)。

正如 Willem Van Onsem 所说,您可以使用 fromMaybe。但是,还有其他选项可能更适合您的特定用例。 (虽然从你的代码中不清楚你的用例是什么,所以我只列出一些选项。)

如果您确定您要查找的值将在列表中的某处,通常是因为您刚刚将其从同一个列表中拉出使用某种折叠,你可以使用 fromJustfromJustfromMaybe 类似,只是它不将附加的第一个参数作为后备值,而是在该值不在列表中时抛出错误。人们会争论你是否应该使用会抛出错误的函数(这些函数被称为 "partial," 因为它们只处理部分输入域),因为当假设被证明是是错误的,但在小心控制的情况下它们是有用的。

fromJust (Just 10)
> 10

fromJust Nothing
> *** Exception: Maybe.fromJust: Nothing

根据您程序的语义,将您的函数签名更改为 return 和 Maybe whatever 而不是 whatever 可能更符合习惯。在这种情况下,您应该考虑使用 fmap>>=<$> 之类的东西来传递您的值,而无需解包。在没有看到更多代码的情况下,我无法告诉您这是否适合您的程序,但对于大多数用例,fromMaybe 不是正确的方法。

fmap (+ 5) (Just 10)
> Just 15

fmap (+ 5) Nothing
> Nothing

Just 10 <$> (+ 5)
> Just 15

Nothing <$> (+ 5)
> Nothing

Just 10 >>= (\x -> if even x then Just $ x `div` 2 else Nothing)
> Just 5

Just 5  >>= (\x -> if even x then Just $ x `div` 2 else Nothing)
> Nothing

Nothing >>= (\x -> if even x then Just $ x `div` 2 else Nothing)
> Nothing

使用 -1 之类的值来指示失败意味着程序的其余部分需要知道 -1 指示失败状态。这些类型的失败值通常需要与正常的 return 值分开处理,这正是 Maybe 类型旨在使其更优雅的用例。是否应该展开 Maybe 的快速测试是查看程序中是否有任何地方进行模式匹配(或使用守卫或 ifcase 等.) 尝试在其他地方捕获此 -1 以触发特殊行为。如果你是,那么你不应该展开 Maybe(这里)。