List 从Haskell中的列表中获取优先权

List 从Haskell中的列表中获取优先权,list,haskell,either,List,Haskell,Either,首先,我有一个(无限)的或s列表,如下所示: x :: A ... f :: A -> Either B A ... xs :: [Either B A] xs = iterate (>>=f) (Right x) 该列表将包含多个右s(始终为有限数),然后重复相同的左值。我需要的是把所有的都放在右边s,然后再放一个左边。在这种特殊情况下,也可以通过更改函数来实现,但我也对最佳通用方法感兴趣。您可以使用将列表拆分为右元素和左元素,然后进行模式匹配以获取第一个左 (righ

首先,我有一个(无限)的
s列表,如下所示:

x :: A
...

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

xs :: [Either B A]
xs = iterate (>>=f) (Right x)
该列表将包含多个
s(始终为有限数),然后重复相同的
值。我需要的是把所有的
都放在右边
s,然后再放一个
左边
。在这种特殊情况下,也可以通过更改函数来实现,但我也对最佳通用方法感兴趣。

您可以使用将列表拆分为
元素和
元素,然后进行模式匹配以获取第一个

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

如果需要将它们都放在同一个列表中,我会这样做:

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

(为什么数据中没有定义
isRight
isLeft
呢?

让我建议一种更具侵入性的改变。而不是

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

x :: A
f :: A -> Writer [A] B
完全忘记xs
。在
f
之前是迭代的单个步骤,现在是递归的;在它将返回
右a
之前,您现在
告诉[a]>>f a
;以前它会返回左b
,现在您可以返回b

如果确实需要,您仍然可以通过
execWriter
evalWriter
访问
Writer
的各个部分,即
[A]
B
(或者使用
runWriter
同时访问它们):

@is7s:这是一个错误类型)已修复。您还可以定义“isRight=other(const False)(const True)”
xs :: [A]
b :: B
(xs, b) = runWriter (f x)