Gap 函数 returns 使用 foldl 或 foldr 列表中两个元素首次出现之间的整数距离。(Haskell)

Gap function that returns the integer distance between first appearance of two elements in a list using either foldl or foldr.(Haskell)

类型定义如下: gap :: (Eq a) => a -> a -> [a] -> Maybe Int 我在这个问题上被困了一个多小时,不知道如何解决这个问题。我知道它需要使用 fold 并且熟悉该主题。 请注意必须使用 foldl 或 foldr。 调用时的输出应该如下所示

gap 3 8 [1..10] =Just 5

gap 8 3 [1..10] =Nothing

gap 'h' 'l' "hello" =Just 2

gap 'h' 'z' "hello" =Nothing

您可能 dropWhile 列表,直到找到起始元素,然后从右侧折叠,从 Nothing 开始,一旦您到达结束元素,将其替换为 Just 1,和 fmaping +1 到累加器。在代码中:

gap :: Eq a => a -> a -> [a] -> Maybe Int
gap from to xs = case dropWhile (/= from) xs of
                      [] -> Nothing
                      (_:rest) -> gap' to rest

gap' :: Eq a => a -> [a] -> Maybe Int
gap' to = foldr f Nothing
    where f x acc | x == to = Just 1
                  | otherwise = (+1) <$> acc

好消息是,如果序列中的元素多次出现,它也能正常工作:

*Main> gap 3 8 $ [1..10] ++ [1..10]
Just 5
*Main> gap 3 8 [1, 2, 3, 3, 3, 8]
Just 3

也许我的解决方案不是很好,但它有效

import Control.Monad
import Data.Function
import Data.Foldable     

(...) = (.) . (.)
gap x y = liftA2 ((guard . (> 0) =<<) ... liftA2 (subtract `on` fst)) 
                 (find ((==x) . snd)) (find((==y) . snd)) . zip [0..]