我正在寻找monad的创造性用途来学习。我已经读过某个地方,在AI中已经使用了monad,但是作为monad新手,我没有看到如何。
请提供源代码和示例用法的链接。请不要standard monads。
答案 0 :(得分:30)
Phil Wadler撰写了many papers on monads,但首先阅读的内容非常有趣,任何程序员都可以访问;它被称为The essence of functional programming。本文包括源代码和样本用法。
我最喜欢的是probability monad;如果你能找到Sungwoo Park的博士论文,它有很多有趣的机器人示例代码。
答案 1 :(得分:16)
还有LogicT(回溯单子变换器,具有公平操作和修剪)。
它具有良好的AI搜索算法价值,因为它具有公平分离的结构,例如,可以轻松实现无限次成功的计算( interleaved )。
它的用法在ICFP'05论文Backtracking, Interleaving, and Terminating Monad Transformers
中有所描述答案 2 :(得分:13)
您可以在博客A Neighborhood of Infinity中找到有趣且高级的monad。我可以注意到Vector Space Monad及其用于rational tangles描述的用法。不幸的是,我认为我不太了解这一点在这里解释它。
答案 3 :(得分:10)
我最喜欢的一个单子是Martin Escardo's search monad。它可以找到on hackage in infinite-search
package。
对于a
类型的一组元素,它是“搜索函数”的monad,即(a -> Bool) -> Maybe a
(在集合中查找与给定谓词匹配的元素)。
答案 4 :(得分:8)
monad的一个有趣用途是解析。 Parsec是标准示例。
答案 5 :(得分:8)
Harpy是一个用于运行时生成x86机器代码的软件包,它使用code generation monad。从描述:
这是一个组合的读者 - 状态 - 异常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
这用于组合子的子组,这些组合子在短时间内需要它们自己的状态。这些只运行状态,不知道调用它的生成器的状态(这有助于使事情更加模块化),但这保留了任何非用户特定的状态,例如生成的当前消息列表和当前的一组警告或错误,以及控制流程(即允许总中止向上流动)。
答案 6 :(得分:7)
阅读关于monad的系列文章,用于对概率和概率过程进行建模:http://www.randomhacks.net/articles/2007/03/03/smart-classification-with-haskell(按照上一个/下一个部分的链接)
答案 7 :(得分:5)
我想列出其他答案中尚未提及的几个单子。
The Omega
monad可用于高效地遍历无限的结果列表。比较:
>>> 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)]
使用更高级的WeightedSearch
monad,还可以为计算分配权重,以便具有较低权重的计算结果首先出现在输出中。
有用的These
data type形成与Monad
类似的Either
,但能够累积错误。该软件包还基于These
定义MonadChronicle
class以及ChronicleT
monad transformer。