是否可以在Haskell中打印状态monad的结果?
我试图理解状态monad并且在一本书中我一直在跟踪供应下面的代码来创建状态monad,但我正在努力解决这个问题,因为我无法直观地查看过程,即看到最终结果。
newtype State s a = State { runState :: s -> (a,s)}
instance Monad (State s) where
return x = State $ \s -> (x,s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
答案 0 :(得分:4)
通常无法以有意义的方式打印功能。如果函数的域很小,则可以从Data.Universe.Instances.Show
包导入universe-reverse-instances以获取打印查找表的Show
实例,该查找表在语义上等效于该函数。导入该模块后,您只需将deriving Show
添加到newtype
声明即可在小状态空间上打印State
操作。
答案 1 :(得分:2)
您提供的代码定义了事物State s a
的种类。它还说State s
是一个monad - 也就是说State s
符合Monad
类型类/接口的东西。这意味着您可以将一个State s
计算绑定到另一个(只要每个类型s
相同)。
所以你的情况类似于定义了Map
那种东西的人的情况,并且还编写了代表Map
符合这种和这样的接口的代码,但是谁没有任何地图,还没有用它们运行任何计算。那时没什么可打印的。
我认为你想看到评估或执行你的状态行为的结果,但你还没有定义任何实际的状态行为,也没有调用runState
(或evalState
或{{ 1}})在他们身上。别忘了你还需要提供一个初始状态来运行计算。
所以也许首先让execState
和s
成为某些特定类型。例如。让a
为s
,让Int
为a
。现在你可以写一些fns,例如Int
和f :: Int -> (Int, Int)
。也许一个函数递减状态,返回新的状态和值,另一个函数递增状态,返回新的状态和值。然后,您可以将g :: Int -> (Int, Int)
包裹在State Int Int
构造函数中,从f
中生成State
。您可以使用>>=
将任意数量的状态操作链接在一起。最后,您可以使用runState
来获取结果值和结果状态,只要您还提供初始状态(例如0)。
答案 2 :(得分:1)
如果只是你想要的结果,如果你只是调试:
import Debug.Trace
import Control.Monad.Trans.State
action :: State [Int] ()
action = do
put [0]
modify (1:)
modify (2:)
get >>= traceShowM
modify (3:)
modify (4:)
get >>= traceShowM