52

我正在寻找 monad 的创造性用途来学习。我在某处读过单子已在 AI 中使用,但作为单子新手,我看不到如何使用。

请包含指向源代码和示例用法的链接。请不要使用标准单子

4

8 回答 8

30

Phil Wadler 写了很多关于 monads 的论文,但首先阅读的那篇很有趣,任何程序员都可以阅读;它被称为函数式编程的精髓。本文包括源代码和示例用法。

我个人最喜欢的是概率单子;如果你能找到Sungwoo Park的博士论文,它有许多来自机器人技术的有趣示例代码。

于 2009-01-09T06:02:26.527 回答
17

还有LogicT(具有公平操作和修剪的回溯单子变换器)。

它对 AI 搜索算法具有很好的价值,因为它具有公平分离的构造,例如,可以轻松地使无限次成功的计算能够被组合(交错)。

它的用法在 ICFP'05 论文Backtracking, Interleaving, and Terminating Monad Transformers中描述

于 2009-01-07T18:03:30.050 回答
13

您可以在博客A Neighborhood of Infinity中找到有趣且高级的 monad 。我可以注意到Vector Space Monad,以及它用于理性缠结描述的用途。不幸的是,我认为我理解得不够好,无法在这里解释。

于 2009-01-05T12:25:50.433 回答
10

我最喜欢的单子之一是Martin Escardo 的搜索单子。它可以在package中的 hackage 上infinite-search找到。

它是一组类型元素的“搜索函数”的单子a,即(a -> Bool) -> Maybe a (在集合中找到与给定谓词匹配的元素)。

于 2009-01-06T02:04:07.787 回答
8

Harpy是一个用于运行时生成 x86 机器代码的包,它使用代码生成单子。从描述:

这是一个组合的 reader-state-exception monad,它处理处理代码缓冲区、发出二进制数据、重定位等的所有细节。

模块 Harpy.X86CodeGen 中的所有代码生成函数都存在于这个 monad 中,并使用它的错误报告工具以及由 monad 维护的内部状态。

库用户可以通过 monad 传递用户环境和用户状态。此状态独立于内部状态,并且可以被更高级别的代码生成库用来在代码生成操作中维护它们自己的状态。

我发现这是一个特别有趣的例子,因为我认为这种模式并不少见:我自己发明了一些非常相似的东西,用于根据从(股票)市场数据馈送中收到的消息为我的应用程序生成一组内部消息。事实证明,让框架跟踪各种“全局”事物,同时编写本身不保持状态的简单操作,这是一种非常舒适的方式。

我更进一步他的想法是拥有一个也可以通过 monad 传递的用户状态(我称之为“子状态”):我有一种在 monad 运行期间切换和恢复状态的机制:

-- | Given a generator that uses different substate type, convert it
-- to a generator that runs with our substate type. As well as the
-- other-substate-type generator, the caller must provide an initial
-- substate for that generator and a function taking the final substate
-- of the generator and producing a new substate of our type. This
-- preserves all other (non-substate) parts of the master state touched
-- by the generator.
--
mgConvertSubstate :: MsgGen msg st' a -> st' -> (st' -> st) -> MsgGen msg st a

这用于在短时间内需要自己的状态的组合子子组。它们仅以它们的状态运行,对调用它的生成器的状态一无所知(这有助于使事情更加模块化),但这保留了任何非用户特定的状态,例如生成的当前消息列表和当前的一组警告或错误,以及控制流(即,允许总中止向上流动)。

于 2009-05-16T11:23:13.513 回答
8

monad 的一个有趣用途是解析。Parsec是标准示例。

于 2009-01-05T12:39:28.003 回答
8

在此处阅读有关用于对概率和概率过程进行建模的 monad 的系列文章:http ://www.randomhacks.net/articles/2007/03/03/smart-classification-with-haskell (点击上一页/下一页的链接)

于 2009-01-05T13:31:57.057 回答
6

我想列出其他答案中尚未提及的几个单子。

枚举和加权搜索单子

Omegamonad可用于高效地遍历无限的结果列表相比:

>>> take 10 $ liftM2 (,) [0..] [0..]
[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9)]

>>> take 10 $ runOmega $ liftM2 (,) (each' [0..]) (each' [0..])
[(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)]

使用更高级的WeightedSearchmonad,还可以为计算分配权重,以便具有较低权重的计算结果首先出现在输出中。

累积错误单子

有用的These数据类型形成Monad类似于Either,但能够累积错误。该包还定义了MonadChronicle以及ChronicleT基于.These

于 2014-05-27T08:54:41.147 回答