5
instance Monad (Either a) where
     return = Left
     fail = Right
     Left x >>= f = f x
     Right x >>= _ = Right x

'baby.hs'のこのコードフラグメントは、ひどいコンパイルエラーを引き起こしました:

Prelude> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )

baby.hs:2:18:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `return' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the expression: Left
In the definition of `return': return = Left
In the instance declaration for `Monad (Either a)'

baby.hs:3:16:
Couldn't match expected type `[Char]' against inferred type `a1'
  `a1' is a rigid type variable bound by
       the type signature for `fail' at <no location info>
  Expected type: String
  Inferred type: a1
In the expression: Right
In the definition of `fail': fail = Right

baby.hs:4:26:
Couldn't match expected type `a1' against inferred type `a'
  `a1' is a rigid type variable bound by
       the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `f', namely `x'
In the expression: f x
In the definition of `>>=': Left x >>= f = f x

baby.hs:5:31:
Couldn't match expected type `b' against inferred type `a'
  `b' is a rigid type variable bound by
      the type signature for `>>=' at <no location info>
  `a' is a rigid type variable bound by
      the instance declaration at baby.hs:1:23
In the first argument of `Right', namely `x'
In the expression: Right x
In the definition of `>>=': Right x >>= _ = Right x
Failed, modules loaded: none.

なぜこれが起こるのですか?そして、どうすればこのコードをコンパイルできますか?助けてくれてありがとう〜

分かりました。そして私はそれがコンパイルされるのを見るためにコードを調整しました:

instance Monad (Either a) where
     return = Right
     Left a >>= f = Left a
     Right x >>= f = f x

正常にコンパイルされます!しかし...さらに質問があります:

instance Monad (Either a)

'どちらか'をモナドにし、' return =Right'を取得しました...どうすれば'return= Left'を取得できますか?私はこれを試しましたが失敗しました:

instance Monad (`Either` a) where
     return = Left
     Right a >>= f = Right a
     Left x >>= f = f x

または:インスタンスモナド(\ x->いずれかのxa)

まったくコンパイルされません!

4

2 に答える 2

9

混乱のほとんどは、LeftとRightが逆方向に使用されているという事実に起因しています。returnの型のみを考慮すると、Monad型クラスからの型は次のようになります。

return :: (Monad m) => b -> m b

m=のインスタンスを定義しようとしているEither aので、returnは次のタイプである必要があります。

return :: b -> Either a b

次のタイプのLeftとして定義しています。

Left :: a -> Either a b

の左側がどのように->異なるかに注意してください。

于 2010-04-06T17:41:37.023 に答える
3
  1. returnはタイプが必要ですがforall b. b -> Either a b、Leftはタイプがありforall c. a -> Either a cます。あなたはおそらくここに欲しいでしょう。
  2. failタイプが必要ですがforall b. String -> Either a b、Rightはタイプforall b. b -> Either a bがあるので、b=StringそれがString -> Either a String適合しない場合。
  3. >>=タイプを持つ必要がありますEither a b -> (b -> Either a c) -> Either a cが、常にタイプではなくRight x >>= _ = Right xタイプの値を返します。Either a bEither a c
  4. Left x >>= f = f xaxにはタイプがfありますが、タイプは。であるため、機能しませんb -> c
于 2010-04-06T17:39:11.640 に答える