當我這樣做:定製MonadState例如
cabal sandbox init
cabal update
cabal install hakaru
cabal repl
λ> :l simple.hs
λ> sample test []
與simple.hs
包含:
{-# LANGUAGE MultiParamTypeClasses #-}
import Language.Hakaru.ImportanceSampler
import Control.Monad.State
instance MonadState Int Measure
test :: Measure Int
test = put 1 >> get >>= \i -> return i
我的電腦運行的內存。
如何才能成功使Measure
單元成爲MonadState
的實例(即test
的返回值高於1
)? Measure
類型已經是Monad
的一個實例,其中bind
和return
已定義。是否有一些默認方式可以根據lift
,bind
和return
來定義MonadState
的put
和get
以使其正常工作?我想:
get = lift get
put = lift . put
,但我不能讓(變壓器?)類型制定:
simple.hs:6:9:
Couldn't match type ‘t0 m0’ with ‘Measure’
Expected type: Measure Int
Actual type: t0 m0 Int
In the expression: lift get
In an equation for ‘get’: get = lift get
simple.hs:7:9:
Couldn't match type ‘t1 m1’ with ‘Measure’
Expected type: m1() -> Measure()
Actual type: m1() -> t1 m1()
In the first argument of ‘(.)’, namely ‘lift’
In the expression: lift . put
我想我需要相反的堆棧順序 - 類似'test :: Measure(State Int())',因爲我想在''返回值''上做'sample :: Measure a - > [] - > IO [(a,P) test'。 現在就試試這個......感謝您的快速響應! – KarlC 2014-12-04 20:32:57
@KarlC StateT monad在內部執行「反向命令」;所有monad變壓器都這樣做。例如,'MaybeT'定義爲:'newtype MaybeT ma = MaybeT {runMaybeT :: m(Maybe a)}',所以'MaybeT IO()'是I/O程序的類型,如果它完成了,將包含'Nothing'或者'Just()'。同樣,'StateT'被定義爲'newtype StateT sma = StateT {runStateT :: s - > m(a,s)}',所以一旦你運行了測試startState,你就會有一個Measure(Int,Int)實例。 – 2014-12-04 20:51:59
'test :: StateT Int Measure Int'現在正在爲我執行這個技巧,以及'runStateT'來獲取'Measure(Int,Int)'。仍然試圖圍繞着Haskell在線wiki的'MaybeT'和'StateT'示例的具體內容,以及可以推廣到其他monad的內容...... – KarlC 2014-12-04 21:15:29