在最近一篇关于他写的概率单子的博客文章中,Mark Dominus 写道:“所以我觉得我终于到了,单子明智。”
我的第一个 monadic 程序是使用parsec和Maybe monad对Project Euler问题 32的一个尴尬解决方案。
当灯终于为你打开时,你在做什么?至少提供您编写的代码的草图。知道您现在所知道的,您将如何改进它以及为什么?
在最近一篇关于他写的概率单子的博客文章中,Mark Dominus 写道:“所以我觉得我终于到了,单子明智。”
我的第一个 monadic 程序是使用parsec和Maybe monad对Project Euler问题 32的一个尴尬解决方案。
当灯终于为你打开时,你在做什么?至少提供您编写的代码的草图。知道您现在所知道的,您将如何改进它以及为什么?
当我意识到我可以使用 monad 进行解析和解释时,我第一次尝试就能够在 F# 中为类似 LUA 的动态编程语言编写我的第一个迷你解释器。一流的延续!、环境、可变状态、调试——所有这些都只是一个大的 monad 转换器堆栈。
这不是对您问题的完全正确的回答,因为它不是真正的编程任务,但是Learn You A Haskell从 Functors 到 Applicatives 再到 Monads 以一种非常清晰的方式对我有很大帮助。
一些基于采样的随机计算代码。« ma » 类型是« a » 类型的随机变量,« a -> mb » 是“随机函数”。随机变量可以通过这种方式非常简单地处理。« replicateM n » 用于从同一变量中获取独立样本。
do 表示法也很好:x <- y 表示 x 是来自随机变量 y 的样本。
没有什么。在几个月没有尝试理解 monad 而是做其他事情之后,下一次我想到 monad 时,我注意到我理解了它们。(这往往发生在其他领域。)
为了记录,最有帮助的事情是考虑加入而不是 (>>=),并意识到加入 (:: m (ma) -> ma) 基本上是在说“而不是我可以运行的计算 A产生一个计算 B(我可以运行它来获得 a 类型的值),给我一个新的计算 C,它同时运行 A ,然后一步运行得到的 B”,所以它非常像无论您使用的是哪个 Monad,都只是上一级。使用 fmap 您可以生成 m (m (m (m (m (ma))))) 类型的计算,使用 join 您可以将它们展平,并且您可以一起创建任意的计算序列(并且“return”是琐碎的计算)。顺序性是 Monad 捕捉到的本质。
对我来说,它是在 QuickCheck “Gen” monad(用于创建随机值)上创建一个变体。我想测试一些有状态的东西,所以我将“Gen”重写为一个 monad 转换器,并将它与一个 State monad 堆叠起来。在那里的某个地方,灯泡亮着。