使用mtl,派生MonadState似乎让make状态操作正常解除了:
: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 ()
我应该做些什么才能让变形金刚工作?
答案 0 :(得分:6)
你应该使用mtl
来完成这项工作。 mtl
和transformers
并非真正的竞争对手 - mtl
depends on变形金刚!它的存在是为了添加使用函数依赖关系的类MonadState
,因此它们不必是核心(Haskell-98)类型定义的一部分。还有一个使用类型系列的包(monads-tf
),它也与transformers
兼容(但实际上,你不应该使用它)。
也许我应该问:你为什么“从mtl转换为变形金刚”?
答案 1 :(得分:1)
MonadState
实例位于包monads-tf
或monads-fd
中,具体取决于您是使用类型函数还是函数依赖项。我尝试使用monads-tf
(因为这是我更喜欢的包),GHC无法为MonadState
派生St
实例,所以你必须自己编写一个。{1}}。
{-# 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)