在Connect4游戏中:
我的想法是:
这种想法正确吗?
假设以上内容正确,其中哪一项正确?
我赞成第二种选择,对我来说更有意义。
我可以用这种方式堆叠这些单子吗(状态,IO)?
答案 0 :(得分:2)
State
实际上定义为monad变换器StateT[F[_], S, A]
的类型别名,其中F[_]
是效果类型。该别名用F[_]
修复了Eval
,因此看起来像type State[S, A] = StateT[Eval, S, A]
。就您而言,您应该只定义自己的IO状态,例如type IOState[S, A] = StateT[IO, S, A]
。
StateT[IO, S, A]
对应于IO[S => IO[(S, A)]]
,我认为它是更有用的堆栈,因为您现在可以轻松地使用此堆栈将代码与使用IO的其余应用程序连接起来。
在猫的国家文档中的interleaving effects部分中,您可以找到更多有关将状态monad与效果StateT
叠加的monad的信息。
答案 1 :(得分:1)
我认为您应该只编写一个工作程序并在以后对其进行概括/重构,而不是过度努力。
您需要State[S, A]
用于业务逻辑,IO[A]
用于与控制台进行交互。但是您不必混合。
然后在编写用户交互循环的主类中,您可以利用StateT
来统一这两种类型。
顺便说一下,IO[State[S,A]]
看起来不是非常有用的类型。它说您可以从现实世界中读取State[S, A]
。 State
是一个函数。没有明智的方法可以从现实世界中读取功能。因此,很可能您需要功能不那么强大的产品。当然,在monad变形金刚的上下文中,这种类型是有意义的。