如何在Haskell中打印State Monad的结果?

时间:2016-04-15 19:05:39

标签: haskell monads

是否可以在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

3 个答案:

答案 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}})在他们身上。别忘了你还需要提供一个初始状态来运行计算。

所以也许首先让execStates成为某些特定类型。例如。让as,让Inta。现在你可以写一些fns,例如Intf :: 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