鉴于List[Either[A,B]]
,我可以在Haskell中使用sequence
来提取整个List
Right[B]
或Left[A]
。
Prelude> sequence [Left "bad", Right 555]
Left "bad"
Prelude> sequence [Right 4534, Right 555]
Right [4534,555]
我不确定此方法是否符合sequence
的定义,但它是处理List[Either[A,B]] => Either[A, List[B]]
的一个很小的功能。
scala> def f[A, B](es: List[Either[A, B]]): Either[A, List[B]] = es match {
| case Right(x) :: xs => f(xs).right.map(y => x :: y)
| case Nil => Right(Nil)
| case left @ Left(_) :: _ => left
| }
但是我收到了这个我不理解的错误。
<console>:10: error: type mismatch;
found : scala.collection.immutable.::[Either[?A3,?B3]] where type ?B3 <: B (this is a GADT skolem), type ?A3 <: A (this is a GADT skolem)
required: Either[A,List[B]]
case left @ Left(_) :: _ => left
^
我在这里做错了什么?
答案 0 :(得分:6)
错误消息显示left
的类型为Either[A, B]
,但f
的预期类型为Either[A, List[B]]
。
你需要在案例中解构Left,然后在表达式中重构它。这看起来很愚蠢,但你要记住,分支中的Left(x)
被标记为与你想要的类型不同。
| case Left(x) :: _ => Left(x)
Haskell会给你一个类似的错误:
f :: Either a b -> Either a [b]
f l@(Left x) = l
Couldn't match type ‘b’ with ‘[b]’
‘b’ is a rigid type variable bound by
the type signature for f :: Either a b -> Either a [b]
at /Users/Jake/Code/Haskell/L.hs:3:6
Expected type: Either a [b]
Actual type: Either a b
Relevant bindings include
l :: Either a b (bound at /Users/Jake/Code/Haskell/L.hs:4:3)
f :: Either a b -> Either a [b]
(bound at /Users/Jake/Code/Haskell/L.hs:4:1)
In the expression: l
In an equation for ‘f’: f l@(Left x) = l