如何在 Haskell 中打印 State Monad 的结果?
How to print the result of a State Monad in Haskell?
是否可以在 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
通常不可能以有意义的方式打印函数。如果函数的域很小,您可以导入 Data.Universe.Instances.Show
from the universe-reverse-instances 包以获得一个 Show
实例,该实例打印在语义上等同于该函数的查找 table。导入该模块后,您可以简单地将 deriving Show
添加到 newtype
声明中,以便能够在较小的状态空间上打印 State
操作。
如果这只是你想要的结果,如果你只是调试:
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
您提供的代码定义了 State s a
的 种类 。而且它还说 State s
是一个 monad——也就是说,那种东西 State s
是符合 Monad
typeclass/interface 的。这意味着您可以将一个 State s
计算绑定到另一个(只要每个 s
的类型相同)。
所以你的情况类似于某人已经定义了 Map
是什么东西,并且还写了代码说 Map
符合这样那样的接口,但谁没有任何地图,还没有 运行 使用它们进行任何计算。那就没什么可打印了。
我认为您想查看评估或执行状态操作的结果,但您尚未定义任何实际状态操作,也没有调用 runState
(或 evalState
或execState
) 在他们身上。不要忘记您还需要为 运行 计算提供初始状态。
所以也许可以从让 s
和 a
成为某些特定类型开始。例如。设 s
为 Int
并设 a
为 Int
。现在你可以去写一些 fns,例如f :: Int -> (Int, Int)
,以及 g :: Int -> (Int, Int)
。也许一个函数递减状态,返回新的状态和值,而另一个函数递增状态,返回新的状态和值。然后你可以通过将 f
包装在 State
构造函数中来从 f
中创建一个 State Int Int
。您可以使用 >>=
将任意数量的状态操作链接在一起。最后,您可以对此使用 runState
来获取结果值和结果状态,只要您还提供初始状态(例如 0)即可。
是否可以在 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
通常不可能以有意义的方式打印函数。如果函数的域很小,您可以导入 Data.Universe.Instances.Show
from the universe-reverse-instances 包以获得一个 Show
实例,该实例打印在语义上等同于该函数的查找 table。导入该模块后,您可以简单地将 deriving Show
添加到 newtype
声明中,以便能够在较小的状态空间上打印 State
操作。
如果这只是你想要的结果,如果你只是调试:
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
您提供的代码定义了 State s a
的 种类 。而且它还说 State s
是一个 monad——也就是说,那种东西 State s
是符合 Monad
typeclass/interface 的。这意味着您可以将一个 State s
计算绑定到另一个(只要每个 s
的类型相同)。
所以你的情况类似于某人已经定义了 Map
是什么东西,并且还写了代码说 Map
符合这样那样的接口,但谁没有任何地图,还没有 运行 使用它们进行任何计算。那就没什么可打印了。
我认为您想查看评估或执行状态操作的结果,但您尚未定义任何实际状态操作,也没有调用 runState
(或 evalState
或execState
) 在他们身上。不要忘记您还需要为 运行 计算提供初始状态。
所以也许可以从让 s
和 a
成为某些特定类型开始。例如。设 s
为 Int
并设 a
为 Int
。现在你可以去写一些 fns,例如f :: Int -> (Int, Int)
,以及 g :: Int -> (Int, Int)
。也许一个函数递减状态,返回新的状态和值,而另一个函数递增状态,返回新的状态和值。然后你可以通过将 f
包装在 State
构造函数中来从 f
中创建一个 State Int Int
。您可以使用 >>=
将任意数量的状态操作链接在一起。最后,您可以对此使用 runState
来获取结果值和结果状态,只要您还提供初始状态(例如 0)即可。