私はsome EitherT
monad transformer, as suggested from real world haskell chapter 18と書こうとしていました。失敗すると、String以外の引数を取ることができますか?
newtype EitherT e m a = EitherT {
runEitherT :: m (Either e a)
}
私EitherT
はそのEither
タイプのLeft error
とRight result
を持つことになり、エラーとしてそれらを保つ、left
値で停止している間Right
値を生成するすべての計算をバインドします。
私のコードは、以下の(命令的スタイルのために申し訳ありません)です:
bindET :: (Monad m) => (EitherT e m a) -> (a -> EitherT e m b) -> (EitherT e m b)
x `bindET` f = EitherT $ do
mx <- runEitherT x
case mx of
Right success -> runEitherT (f success)
Left error -> return (Left error)
instance (Monad m) => Monad (EitherT e m) where
return a = EitherT $ return (Right a)
(>>=) = bindET
fail e = EitherT $ return (Left e)
私は、EitherT
変圧器は非常に簡単だったためMonad
インスタンスを書いて思った私は、GHCiのにコードをロードするときしかし、私はこの不可解なエラーメッセージが表示されます。
EitherT.hs:30:18:
Could not deduce (e ~ [Char])
from the context (Monad m)
bound by the instance declaration at EitherT.hs:27:10-41
`e' is a rigid type variable bound by
the instance declaration at EitherT.hs:27:10
Expected type: EitherT e m a
Actual type: EitherT String m a
In the expression: EitherT $ return (Left e)
In an equation for `fail': fail e = EitherT $ return (Left e)
In the instance declaration for `Monad (EitherT e m)'
Failed, modules loaded: none.
fail
関数は引数としてString
を取るように固定されているようだ - そのような場合も、その後、私のEitherT e m a
はEitherT String m a
AになりますすべてLeft
の値はLeft String
になります。 EitherT
モナドは計算のエラーを示すために任意のタイプの値をLeft
として取ってほしいです。それをどうすれば実現できますか?
これは実際問題であり、歴史的には断片化が起こりました。 ['EitherT'](https://hackage.haskell.org/package/either-4.4.1/docs/Control-Monad-Trans-Either.html#t:EitherT)、[' ErrorT'](https:///hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Error.html#t:ErrorT)、['ExceptT'](https://hackage.haskell.org/package/mtl) -2.2.1/docs/Control-Monad-Except.html#t:ExceptT)はすべて、探索したい解決策の空間内の微妙に異なる点を表します。 –