2016-04-15 53 views
0

是否可以在Haskell中打印state monad的结果?如何在Haskell中打印State Monad的结果?

我试图了解状态monads,并在一本书中我一直在提供下面的代码来创建一个状态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 
+1

“如何打印状态单子”与“如何打印状态单子的结果”是完全不同的问题,至少如果我将前者理解为打印_a“状态”action_,后者将其打印为_打印一次执行“状态”动作的结果。你的意思是? – leftaroundabout

+0

@leftaroundabout结果抱歉。 –

回答

2

您提供的代码定义种事情State s a是。它也表示State s是一个单子 - 也就是说,State s符合Monad类型类别/接口。这意味着您可以将一个State s计算绑定到另一个(只要类型s在每个中相同)。

因此,您的情况类似于定义Map所属类型的人的情况,并且还编写了代码,说明Map符合此类接口,但没有任何地图,并且还没有对它们进行任何计算。那么没有什么可以打印的。

我想你想看到评估或执行的国家行动的结果,但还没有定义任何实际的政府行为呢,也没有你要求他们runState(或evalStateexecState)。不要忘记你还需要提供一个初始状态来运行计算。

因此,可能首先让sa为某些特定类型。例如。让sInt并让aInt。现在你可以写一些fns,例如f :: Int -> (Int, Int)g :: Int -> (Int, Int)。也许一个函数递减状态,返回新的状态和值,另一个函数递增状态,返回新的状态和值。然后,通过将它包装在State的构造函数中,可以制作State Int Int,f。你可以使用>>=来连接许多国家的行为,只要你喜欢。最后,您可以使用runState来获得结果值和结果状态,只要您还提供初始状态(例如0)即可。

+0

@liminalishit非常感谢你的回答,这真的很有帮助!我做了一个函数f来增加状态。我有点不确定如何做链部分抱歉,请你给我一个例子。谢谢 –

+0

让'f = \ x - >(x + 1,x + 1)',让'g = State(f)>> = State(f)'。这代表一个状态动作,使状态两次增加。 'runState g 0'应该返回'(2,2)'。等价地,如果'h = \ x - >返回(x + 1,x + 1)',并且j ='StateT(h)>> = StateT(h)',那么runStateT h 0返回' 2)'。这可能会让你感觉到“State”monad的工作方式。但是使用'get'' put'和'modify'来构建状态动作,通常来自'mtl'或'transformers'这样的包,通常如何使用'State'单元,并且与您可能会遇到的命令式样非常相似习惯于使用命令式语言。 – liminalisht

4

通常不可能以有意义的方式打印功能。如果函数的域很小,则可以从universe-reverse-instances包中导入Data.Universe.Instances.Show以获得一个Show实例,该实例打印一个与该函数在语义上等效的查找表。通过导入该模块,您可以简单地将deriving Show添加到newtype声明中,以便能够在小型状态空间上打印State操作。

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 
+0

谢谢,但我得到的错误不在范围内放,修改,修改,获取,修改,修改,获取? –

+0

这是使用通过导入Control.Monad.Trans.State – Gurkenglas

+0

可访问的库提供的函数谢谢,我得到一个错误“模糊发生'状态'它可以指'Main.State'或'Control.Monad .Trans.State.State'“?@Gurkenglas –