0

mtl を使用すると、MonadState を派生させると、make state 操作が適切に解除されるようです。


:set -XGeneralizedNewtypeDeriving
import Control.Applicative (Applicative)
import Control.Monad.Trans ( MonadIO, liftIO )
import Control.Monad.State (MonadState, evalStateT, modify, StateT, gets)

data State = State { int:: Int }
newtype St a = St { unSt :: StateT State IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadState State)

let testLift = gets int >> return () :: St ()

トランスフォーマーの場合、MonadState はありません


:set -XGeneralizedNewtypeDeriving
import Control.Monad.Trans.State.Strict (runStateT, evalStateT, modify, StateT, gets)
import Control.Monad.IO.Class ( MonadIO, liftIO )
import Control.Applicative (Applicative)


data State = State { int:: Int }
newtype St a = St { unSt :: StateT State IO a } deriving (Functor, Applicative, Monad, MonadIO)


let testLift = gets int >> return () :: St ()
Couldn't match type `StateT State m0' with `St'
Expected type: St Int
  Actual type: StateT State m0 Int
In the return type of a call of `gets'
In the first argument of `(>>)', namely `gets int'
In the expression: gets int >> return () :: St ()

これを変圧器で機能させるにはどうすればよいですか?

4

2 に答える 2

6

あなたはmtlそれを機能させるために使用することになっています。mtl実際には競合他社でtransformersはありません -トランスフォーマーmtl に依存しています! MonadStateコア (Haskell-98) 型定義の一部である必要がないように、機能依存関係を使用するようなクラスを追加する必要があります。代わりに型ファミリを使用するパッケージ ( monads-tf) もありますが、これも と互換性がありtransformersます (ただし、実際には使用しないでください)。

多分私は尋ねるべきです: なぜ「mtl からトランスフォーマーに切り替える」のですか?

于 2013-07-14T20:54:04.387 に答える
1

MonadStateインスタンスは、型関数または関数依存のどちらを使用するかに応じて、パッケージまたはにありますmonads-tf。(私が好むパッケージなので) でmonads-fd試してみましたが、GHC は のインスタンスを派生させることができなかったので、自分で作成する必要があります。monads-tfMonadStateSt

{-# OPTIONS_GHC -package transformers -package monads-tf -hide-package mtl #-}
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}

import Control.Monad.Trans.State.Strict (runStateT, evalStateT, modify, StateT)
import Control.Monad.State.Class  -- MonadState class
import Control.Monad.IO.Class ( MonadIO, liftIO )
import Control.Applicative (Applicative)

data State = State { int:: Int }
newtype St a = St { unSt :: StateT State IO a } deriving (Functor, Applicative, Monad, MonadIO)

instance MonadState St where
  type StateType St = State
  get = St get
  put x = St (put x)
于 2013-07-14T18:40:47.187 に答える