【发布时间】:2015-01-18 18:55:05
【问题描述】:
严格的状态 monad 是这样定义的:
m >>= k = State $ \s ->
case runState m s of
(a, s') -> runState (k a) s'
但这仍然会泄漏内存,因为 a 和 s' 未被评估。例如,我们可能有一个函数f,它将一个大对象作为输入并快速返回(a, s'),但只要a 未计算,f 的输入就不能被GC'ed。
一种可能的解决方案是让f 返回seq a (a, s'),但如果我们使用MonadRandom 之类的东西,并且状态与f 隔离开来,这并不总是可行的。是否有这样定义的版本:
m >>= k = State $ \s ->
case runState m s of
(!a, !s') -> runState (k a) s'
这是否已经存在于任何地方的图书馆中?
【问题讨论】:
-
@GabrielGonzalez 在制作更严格的变压器方面做了一些工作,例如more strict WriterT。
-
我很想只在
s上严格执行此操作。如果需要严格的a,我认为调用者可以简单地m >>= \ !a -> ...达到相同的效果。 -
在
a中设置严格会违反单子定律,所以你不想那样做。当在s中严格要求时,您还必须将return更改为return x = State $ \ !s -> (x, s),否则它会保留身份规则。 -
试试看。您可能会违反单子定律(并引入例如立即失败)。
-
@dfeuer 我想你可以把你的评论变成一个答案,把它作为一个未回答的问题来结束?
标签: haskell lazy-evaluation state-monad