2010-12-06 10 views
4

ブック実世界Haskellのからこのセクションhttp://book.realworldhaskell.org/read/monad-transformers.html#id659032は新しいモナド変圧器を書くとき、私たちは手作業などMonadStateMonadIO、のインスタンスを導出しなければならないことを示唆しています。なぜボイラープレート新しいモナド変圧器を書き

しかし私は以下を試してコンパイルしました。なぜそれは図書館で行われていないのですか?我々はtMonadTransで、mは、他のすべてが自動的に次のように導出することができない理由Monad、であることを知っていたら、その後

newtype MaybeT m a = MaybeT { 
    runMaybeT :: m (Maybe a) 
} 

instance Monad m => Monad (MaybeT m) where -- blah blah 

instance MonadTrans MaybeT where 
    lift = MaybeT . (liftM Just) 

は、私がMaybeTモナド変圧器を持って言いますか?

instance (MonadTrans t, Monad (t m), MonadIO m) => MonadIO (t m) where 
    liftIO = lift . liftIO 

instance (MonadTrans t, Monad (t m), MonadState s m) => MonadState s (t m) where 
    get = lift get 
    put = lift . put 

著者たちはそれぞれの新しいMonadTransため、手動でこれを行うには持っているか、私は彼が間違って取得するということですか?

はどうもありがとうございました:)

+3

GHCの拡張であるGeneralizedNewtypeDerivingは、モナドクラスのいくつかのインスタンスを自動的に作成できますが、どのクラスのインスタンスのリストも見つけられませんでした。上のMonadIOやMonadStateのような完全にパラメトリックなインスタンスは "悪いフォーム"です。 FUZxxlには以下のように、特殊化の用途が異なる場合がありますが、クラスメソッドが「明らかにパラメトリック」であるが、明示的なインスタンスが1つしかない場合は、クラスメソッドではなくプレーンなパラメトリック関数である必要があります。 –

+0

ステファンありがとうございます。しかし、私はここで少し遅いです。あなたの最後の文章は、私のコードのどの部分を指していますか? (明らかにパラメトリックなクラスメソッドですが、明白なインスタンスは1つだけです)。もっと説明できますか? – Phil

+1

こんにちは。最後の文は一般的なもので、コードとは関係ありません。しかし、putとgetが "標準ライブラリ"のクラスメソッドであるという論理を逆転させることで、あまりにも一般化されていない関数としては意味があると合理的に期待できるので、結果的には型固有のケースを書く必要があります。 –

答えて

4

彼らはこれをしない理由は非常に単純です:彼らはこれを追加する場合

  1. まず、それは古いコードの多くを破るだろう、ので、 GHCが自動的に定義されたインスタンスと手動で定義されたインスタンスを決定するように、UndecidableInstancesのようなものが必要です。これは非常に面倒です。
  2. 上記と異なるインスタンスを定義する場合は、パフォーマンス上の理由から、またはハッキングを行うために、私は、このインスタンスがビルドされている場合、カスタマイズされたインスタンスを定義することの無力/高コスト(これはGHCにどのインスタンスが必要かを伝えるトリッキーのため)よりも、この小さな定型文が好ましいと思います。
関連する問題