Haskell返回搜索项目的位置

时间:2018-03-13 05:12:43

标签: haskell

我有以下Haskell代码,它从列表中返回所请求元素的实例(只是第一个实例),如果元素不存在则返回0。我试图返回列表中元素的位置,但不知道如何(我对编程很新)。

e.g。 'm''有些'正在返回m但我希望它返回3。

findMe x [] = 0
findMe x (y:ys) = if x == y
                        then x
                        else findMe x ys

2 个答案:

答案 0 :(得分:3)

试试这个。如果由于元素不存在而返回0,我认为它是1索引开始。

findMe x list = findMeP list 1
  where
    findMeP [] _ = 0
    findMeP (y:ys) n
      | x == y    = n
      | otherwise = findMeP ys (n + 1)

作为演示,请查看this

答案 1 :(得分:3)

虽然之前的答案是正确的,但这是一个我更喜欢的解决方案,因为它使用了基本库中的基本构建块,并避免了显式的递归。

import Data.List (find) {- for find :: (a -> Bool) -> [a] -> Maybe a -}

findMe :: Eq a => a -> [a] -> Maybe (Int, a)
findMe x = find ((== x).snd) . zip [1..]

该函数返回元素及其索引,从开始计算,包含在Maybe类型中。如果未找到该元素,则返回Nothing

要单独提取元素或索引,可以在fst结果上映射sndMaybe函数:

findMeIndex = fmap fst . findMe
findMeElem  = fmap snd . findMe

示例:

findMe 'c' ['a','b','c','d'] == Just (2,'c')
findMe 'z' ['a','b','c','d'] == Nothing

findMeIndex 'c' ['a','b','c','d'] == Just 2
findMeIndex 'z' ['a','b','c','d'] == Nothing

如果您需要从1开始计算,则可以将[0..]替换为[1..]。在任何一种情况下,将结果包装在Maybe中最好返回一些特殊值来表示缺少元素(比如-10),因为那样用户就不会误会解释你的结果。例如,如果您从1计算并在失败时返回0,并且有人使用您的函数错误地认为您从0开始计算,则他们可能会将失败解释为已找到该元素在第一个位置。相反,用户被迫明确处理故障情况。

该功能的工作原理如下。 zip [0..]生成一个将每个元素与其索引耦合的对的列表,从零开始([0..]是无限列表[0,1,2,3,..])。然后,find扫描列表(与OP的原始代码完全相同),返回函数((== x).snd)返回True的第一个元素,包含在Maybe中如果找到,则输入,否则输入Nothingfind寻找哪个元素?请记住,find附带列表。因此,通过将snd函数与(== x)组合,我们找到第二个组件等于x

的对