如何将函数映射到列表并在满足条件时停止并告诉我它是停止还是到达结束?

Phi*_*eau 7 haskell functional-programming

我想在列表上应用一个函数,但是如果在任何时候函数返回的结果是某种类型的,那么我不想继续迭代其余的元素。

我知道我可以用这个功能实现这一点:

example p f ls = takeWhile p $ map f ls
Run Code Online (Sandbox Code Playgroud)

问题是我想知道它是否到达了列表的末尾,或者它是否没有这样做。

想到了这个功能,但是好像有点麻烦:

haltmap :: Eq a => (a -> Bool) -> (b -> a) -> [a] ->  [b] -> Either [a] [a]
haltmap _ _ acc [] = Right acc
haltmap p f acc (h:t)
  | p output = Left acc
  | otherwise = haltmap p f (acc ++ [output]) t
  where output = f h
Run Code Online (Sandbox Code Playgroud)

我使用 Left 和 Right 来知道它是否通过了整个列表。

我相信有更好的方法来做到这一点。

Dav*_*her 8

我会为此使用跨度。就像 takeWhile 一样,但它为您提供了一对列表的其余部分以及匹配部分,如下所示:

> span (<3) [1,2,3,2,1]
([1,2],[3,2,1])
Run Code Online (Sandbox Code Playgroud)

然后你可以检查余数是否为空:

haltmap :: (a -> Bool) -> (b -> a) -> [b] -> Either [a] [a]
haltmap p f xs = (if null rest then Right else Left) ys
  where
    (ys, rest) = span p (map f xs)
Run Code Online (Sandbox Code Playgroud)