7

MonadState sHaskellはT1以下のインスタンスを導出できますが、T2これは非常に類似したタイプではありません。T2のインスタンスをMonadState s自動的に派生できるようにするには、コードをどのように変更すればよいですか?

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.Reader
import Control.Monad.State

newtype T1 r s a = 
  T1 { runT1 :: ReaderT r (State s) a }
  deriving (Monad, MonadReader r, MonadState s)

newtype T2 r s a = 
  T2 { runT2 :: StateT r (State s) a }
  deriving (Monad, MonadState r, MonadState s)
4

1 に答える 1

9

タイプに の 2 つのインスタンスを持たせることはできませんMonadState。これは、MonadStateが次のように定義されているためです。

class Monad m => MonadState s m | m -> s where
    get :: m s
    set :: s -> m ()
    state :: (s -> (a, s)) -> m a

重要な部分は| m -> s. これには拡張子が必要であり、FunctionalDependencies任意mの について、関連する が自動的に認識されることを示していsます。これは、任意の に対して、有効な選択肢が1 つmしかないことを意味します。したがって、 と not の両方で機能させることはできません。の場合、コンパイラはそれが適用される基礎となるモナドをどのように知るのでしょうか? この場合、 、 、 、 、、 、 のように、サフィックスを付けて関数を作成すると、コードの理解と操作がはるかに簡単になることもわかると思います。sMonadState r mMonadState s mr ~ sr ~ sgetputgetInnersetInnergetOutersetOuter

于 2014-09-05T20:40:14.163 に答える