当我这样做时:
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
monad成为MonadState
的实例(即test
以上返回1
)? Measure
类型已经是Monad
的实例,其中bind
和return
已定义。是否有一些默认方式我可以用MonadState
,put
和get
来定义lift
' s bind
和return
使它工作?我试过了:
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
答案 0 :(得分:3)
Measure
已按以下方式定义:
newtype Measure a = Measure { unMeasure :: [Cond] -> Sampler (a, [Cond]) }
您可以看到没有地方存储您的Int
,因此您无法将其设为MonadState
的正确实例。
如果您想将Measure
扩展为MonadState
,可以使用StateT
monad transformer:
test :: StateT Int Measure Int
test = put 1 >> get >>= \i -> return i
这里发生了什么? StateT s
是一个monad转换器,可让您将State s
monad与任何其他monad组合在一起(在此示例中为Measure
)
答案 1 :(得分:0)
最终为我工作的确切代码是:
import Language.Hakaru.ImportanceSampler
import Language.Hakaru.Distribution
import Control.Monad.State
import System.IO.Unsafe (unsafePerformIO)
test1 :: StateT Int Measure Int
test1 = do
i <- lift $ unconditioned $ categorical [(0,0.25), (1,0.25), (2,0.5)]
j <- lift $ unconditioned $ categorical [(i,0.25), (1,0.25), (2,0.5)]
put (i + j)
k <- get
return k
run_test1 = unsafePerformIO $ empiricalMeasure 10 (evalStateT test1 0) []