2015-03-31 42 views
1

給定一個List[Either[A,B]],我可以使用sequence在Haskell,用於提取整個Right[B] S或Left[A]List序列樣功能Scala中

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 
            ^

我在做什麼錯在這裏?

回答

6

錯誤消息是說left的類型是Either[A, B],但預期類型fEither[A, List[B]]

您需要在案例中解構Left,然後在表達式中重構它。這看起來很愚蠢,但你必須記住分支中的Left(x)標記了與你想要的不同的類型。

| case Left(x) :: _ => Left(x) 

哈斯克爾會給你一個類似的錯誤:

f :: Either a b -> Either a [b] 
f [email protected](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 [email protected](Left x) = l