私は、コンパイラは次のコード(コードのコンパイル)文句ないことに困惑している:私は、例えば、どこかの制約としてMonadIO m
を追加する必要がありました場合にはすぐに、再び私には理にかなってなぜMonadスタックは一般的にMonadIOを派生しますか?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main where
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Except (ExceptT)
main = undefined
newtype Foo e m a = Foo { unFoo :: ExceptT e m a }
deriving (Functor, Applicative, Monad, MonadIO)
deriving instance MonadIO m => MonadIO (Foo e m a)
と確かに私は
deriving instance MonadIO (Foo e m a),
をしようとした場合、コンパイラは文句を言います。
MonadIO m
という制約を追加するときにはliftIO
しか使用できないことに気付きました。スタンドアロンの派生と制約でメソッド2を使用しているかどうかにかかわらず、やはり意味があります。 MonadIO
のインスタンスはの条件でであり、MonadIO m
です。
私はそれだけですか、それとも直感的ですか?
廃止予定の-XDatatypeContexts拡張機能と関連がありますか? GeneralizedNewtypeDeriving
で
私はそれを認識しています。しかし、なぜこれはとても扱いにくいのですか?例えば。私が 'MonadError e'を派生させたとき、後で制約を加える必要はありません。 –
'MonadError e'は全ての' m'に対して有効な 'ExceptT'からの実装が使われるので、' m'に制約を必要としません。 'MonadIO'は' m'の実装を使用する必要があり、そのような実装が存在することを保証しなければならないので、 'm'の制約なしに実装することはできません。それは厄介ではなく、少なくともそれが必要とするほど厄介です。 –
ドキュメントへのリンクを追加しました。 – Koterpillar