从Haskell的列表中获取第一个权利

时间:2012-10-16 18:28:29

标签: list haskell either

首先,我有一个{无限的} Either s列表,它是这样产生的:

x :: A
...

f :: A -> Either B A
...

xs :: [Either B A]
xs = iterate (>>=f) (Right x)

该列表将包含多个Right s(始终为有限数字),然后重复相同的Left值。我需要的是在它们之后取所有Right和一个Left。在这种特殊情况下,也可以通过更改函数来完成,但我也对最佳通用方法感兴趣。

3 个答案:

答案 0 :(得分:9)

让我建议一个更具侵略性的变化。而不是

x :: A
f :: A -> Either B A
xs :: [Either B A]

考虑

x :: A
f :: A -> Writer [A] B

并完全忘记xs。在f之前的迭代的一个步骤,它现在是递归的;在它返回Right a之前的位置,您现在tell [a] >> f a;在它返回Left b之前的位置,您现在return b

如果确实有必要,您仍然可以通过Writer和{{访问[A]的各个部分,即BexecWriter 1}}(或使用evalWriter一次访问它们):

runWriter

答案 1 :(得分:5)

您可以使用spanRight元素和Left元素之间拆分列表,然后模式匹配以抓住第一个Left

(rights, firstLeft : _) = span isRight xs
    where isRight (Right _) = True
          isRight _         = False

答案 2 :(得分:1)

如果你需要将它们全部保存在同一个列表中,我会这样做:

answer = map fst . takeWhile snd $ zip xs (True : map isRight xs)
  where isRight (Right _) = True
        isRight _         = False

(为什么Data.Either中没有定义isRightisLeft?)