返回列表中某个元素的所有位置而不进行递归,但使用列表生成器

Swi*_*ift 2 recursion haskell

我们被要求在Haskell中自己编写一个函数,当给定一个列表并且某个元素返回一个新列表时,该列表包含该列表中该元素的有序位置.

我已经尝试了很长一段时间了,但是我现在使用的那个仍然使用递归,任务说我们不应该使用递归.

allPositionsOf :: (Eq a) => a -> [a] -> [Int]
allPositionsOf e es = [i | i <- [0 .. (length es - 1)], IsAtPos e es i]
    where
         isAtPos :: (Eq a) => a -> [a] -> Int -> Bool
         isAtPos e (x:xs) 0 
                          |x == e    = True
                          |otherwise = False
         isAtPos e (x:xs) i   = findAtPosition xs e (i - 1)
Run Code Online (Sandbox Code Playgroud)

我知道有!! 和其他类似的功能,但是可以只使用列表生成器并使其更简单吗?

Car*_*ten 5

我想你想要这样的东西吧?

allPositionsOf :: Eq a => a -> [a] -> [Int]
allPositionsOf b xs = [ i | (i,x) <- zip [0..] xs, x == b]

?> allPositionsOf 'b' "dfbhjbd"
[2,5]
Run Code Online (Sandbox Code Playgroud)

你几乎已经得到了它 - 我唯一添加了另一个技巧:

zip列出了[0,1,2,...]并排获得indizes和元素,拉出一(index,element)对(这里(i,x)),过滤掉所有内容x == b然后最终从对中返回indizes