2017-08-09 27 views
3

を読むためにはどうすればカスタムタイプのためにモナドの実装を書いた:コンパイラエラー

data Sum a b = 
     First a 
    | Second b 
    deriving (Eq, Show) 

    instance Functor (Sum a) where 
    fmap _ (First x) = First x 
    fmap f (Second y) = Second (f y) 

    instance Applicative (Sum a) where 
    pure = Second 
    First x <*> _ = First x 
    _ <*> First x = First x 
    Second f <*> Second x = Second (f x) 

    instance Monad (Sum a) where 
    return = pure 
    (First a) >>= _ = First a 
    (Second a) >>= k = Second (k a) 

と私はそれが間違っている知っています。コンパイラは文句を言う:

D:\haskell\chapter18\src\SumMonad.hs:39:24: error: 
    * Couldn't match type `b' with `Sum a b' 
     `b' is a rigid type variable bound by 
     the type signature for: 
      (>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) -> Sum a b 
     at D:\haskell\chapter18\src\SumMonad.hs:38:15 
     Expected type: Sum a b 
     Actual type: Sum a (Sum a b) 
    * In the expression: Second (k a) 
     In an equation for `>>=': (Second a) >>= k = Second (k a) 
     In the instance declaration for `Monad (Sum a)' 
    * Relevant bindings include 
     k :: a1 -> Sum a b 
      (bound at D:\haskell\chapter18\src\SumMonad.hs:39:20) 
     (>>=) :: Sum a a1 -> (a1 -> Sum a b) -> Sum a b 
      (bound at D:\haskell\chapter18\src\SumMonad.hs:38:5) 
Failed, modules loaded: none. 

コンパイラのエラーを読むには?

答えて

11
* Couldn't match type `b' with `Sum a b' 

翻訳:I(コンパイラ)はbを期待し、代わりにSum a bを得ました。

`b' is a rigid type variable bound by 
    the type signature for: 
     (>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) -> Sum a b 

翻訳:ので、型変数b>>=具体的な型の値の署名のは、あなたによってが、あなたの呼び出し側によって選びだしすることはできません。あなたは私に何らかの価値を渡すだけではなく、bが型の値として式の型を取ることを期待できます(bは型変数です)。

Expected type: Sum a b 
    Actual type: Sum a (Sum a b) 

翻訳:もっと簡単にするために、私はあなたにもう少し文脈を伝えます。私はSum a bを期待し、あなたは私にSum a (Sum a b)を手渡しました。あなたは今、すでにそれはその関数の実装が生成する必要があります値の型であるため、問題が大胆

 (>>=) :: forall a1 b. Sum a a1 -> (a1 -> Sum a b) ->Sum a b 

にここにあることを、見ることができます。

* In the expression: Second (k a) 
    In an equation for `>>=': (Second a) >>= k = Second (k a) 
    In the instance declaration for `Monad (Sum a)' 

あなたのためのより多くのコンテキスト。 I(コンパイラ)はSecond (k a)はなくSum a bSum a (Sum a b)を入力していることを、方程式ここ

(Second a) >>= k = Second (k a) 

あなたが推測できるで表現

Second (k a) 

が好きではありません。

、さらに便利あなたのためのメッセージ:

* Relevant bindings include 
    k :: a1 -> Sum a b 
     (bound at D:\haskell\chapter18\src\SumMonad.hs:39:20) 
    (>>=) :: Sum a a1 -> (a1 -> Sum a b) -> Sum a b 
     (bound at D:\haskell\chapter18\src\SumMonad.hs:38:5) 

翻訳:k aの結果は、すでにあなたが見るSum a b、ありますか?だから私の以前の(うまくいけば役に立つメッセージ)を考えるなら、Second (k a)Sum a bではないSum a (Sum a b)のタイプになります。