【发布时间】:2016-11-08 21:03:35
【问题描述】:
在我为考试函数式编程学习时,我仍在努力真正理解 Monads。有什么比自己定义更好的方法呢?我定义了这个:
newtype ST a = ST (State -> ([a], State))
type State = StdGen
基本上是 List Monad 和 Random Monad 合二为一。
这个 monad 应该使您能够使用随机函数和列表。
现在麻烦来了,因为我能够定义return 函数,但是>>= 并不能完全做到这一点。
instance Monad ST where
return a = ST $ \g -> ([a], g)
-- M a -> (a -> M b) -> M b
st >>= f = ST $ \s ->
let (x,s') = st s
in (f x) s'
代码灵感来自This paper p.218
有什么解释吗?
【问题讨论】:
-
那么你希望 monad 做什么?我不认为你可以把这种类型变成一个单子。
-
真的,方法是倒退的。你应该从你想要的行为开始,然后写下你需要实现它的类型。我的短语“将这种类型变成 monad”是一个糟糕的短语。
-
我想要的行为是将这样的函数链接在一起(从语义上看):
exmpl :: Int -> StdGen -> ([Int], StdGen) exmpl x gen = [y | y <- [x - 3 .. x + randomR (1, 10) gen] -
f :: a -> ST a b,但x :: [a]。您不能将f应用于x,因此您要么必须选择一个元素(哪个?),要么将其应用于部分或全部元素并弄清楚如何处理所有生成的ST a b值. -
但是“将 [...] 这样的函数链接在一起”意味着是什么?如果你明白你的意思,你写
(>>=)就没有问题了。
标签: haskell monads state-monad