fre*_*low 22 monads haskell design-patterns
在对我的一个答案的评论中,SO用户sdcwc基本上指出了以下代码:
comb 0 = [[]]
comb n =
let rest = comb (n-1)
in map ('0':) rest
++ map ('1':) rest
Run Code Online (Sandbox Code Playgroud)
可以替换为:
comb n = replicateM n "01"
Run Code Online (Sandbox Code Playgroud)
这让我完全惊呆了.
现在我正在寻找教授这些高级概念的教程,书籍或PDF.我不是在寻找一个针对初学者的"什么是monad"教程或者解释其类型的在线参考replicateM.我想学习如何在monad中思考并有效地使用它们,如果你愿意,可以使用monadic"模式".
sdc*_*vvc 11
就拿功能,如sequence,filterM,liftM2,join并认为他们是如何为每个单子工作IO,[],(->) a,Writer,State.例如,sequence对于IO monad,按顺序执行IO操作:
[IO a] -> IO [a]
Run Code Online (Sandbox Code Playgroud)
写下签名并尝试使用它们.有些组合很有趣,有些则更少.
过滤器示例:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Control.Monad
import Control.Monad.State
import Control.Monad.Reader
a = filterM (\x -> do putStrLn $ "Put " ++ show x ++ "?"
fmap (=="Y") getLine)
b = filterM (const [False,True])
c m xs = runState (filterM k xs) 0
where k x = do a <- get
let p = a + x <= m
when p $ put (a+x)
return p
d = filterM (flip id)
Run Code Online (Sandbox Code Playgroud)
a 使用IO过滤列表 - 它向用户询问每个项目.
b不确定地过滤列表 - 每个项目都是不确定的,不包括在内.结果,你获得了powerset.(试试吧!)
c过滤列表,维护状态.在这种情况下,这是贪婪的背包 - 你有容量的背包,m并希望从中插入尽可能多的物品xs.
d过滤列表,保持只读状态.这不好玩.我使用过滤功能作为状态,这给出了flip filter.
单个函数filterM可以完成所有这些操作.
如果您为其他函数编写类似的代码,您将获得足够的直觉来注意其他地方的monadic函数.例如,如何获得以下功能?
dup f x = f x x
Run Code Online (Sandbox Code Playgroud)
那怎么样dup' f x = f x x x?
ste*_*ley 10
从我的角度来看(这当然不是普遍的),我对列表monad无动于衷 - 在你的例子中我(弱)认为,因为有很多列表函数,所以解决方案是巧合的.一元函数而不仅仅是一个函数列表(或通过Data.Traversable或Data.Foldable函数列表的泛化).
对于monadic模式,我更多地考虑效果而不是特定组合器 - 状态模型读写状态,Reader模型只读"状态",Writer模型只写"状态",可能模型偏好(因此它可以模拟错误而没有错误消息) ,Either/Error使用有形错误代码或消息模拟错误.当你掌握效果时 - 你很快意识到你需要将它们结合起来,这样monad变换器才变得重要.
除了"编程的乐趣"之外,还没有关于高级Haskell的书籍 - 这是一本多作者的书,收集了一些完全不同的作品,所以在决定你是否想要一本书之前,有必要浏览一本书. .理查德伯德的新书有很多高级编码的例子,但它用简单优雅的代码完成.虽然它不是一本关于高级语言功能的书,但它是一本非常好的书.
在没有书籍的情况下,论文是最好的地方,因为它们比博客更精致.最相关的是Haskell研讨会(以前称为Haskell研讨会),查看下面的链接,查看将列出所提交论文的会议记录,然后搜索您感兴趣的任何内容 - 在大多数情况下,作者公开发表论文可用.
http://haskell.org/haskell-symposium/
这段代码实际上结合了两个关于Haskell的非常隐含的事实:
以下代码段是等效的:
replicateM n "12"
replicateM n ['1', '2']
replicateM n $ do c <- ['1', '2']
return c
Run Code Online (Sandbox Code Playgroud)
我认为最后一个版本实际上最清楚地显示了在这种情况下会发生什么:我们可以在"1"和"2"之间进行选择,并且这些选择中的n个被链接在一起.一旦你理解了这一点,你就像你需要的Haskell理解一样先进.剩下的就是混淆了一下.
当你超越状态monad及其子集 - 作家和读者 - 并且开始考虑Cont和List,以及它们在回溯,组合和搜索方面的含义时,真正狂野/令人敬畏的东西就是monad.我稍后会提供更多参考资料,但Oleg和Chung-chieh Shan的LogicT论文是一个好的开始:http://okmij.org/ftp/Computation/monads.html
EZ Yang在MR 15的三个monad中的冒险经历:http://themonadreader.files.wordpress.com/2010/01/issue15.pdf
这个问题的答案也可能是有趣的:monad的创造性使用
查看TMR13中的Typeclassopedia.没有其他人建议它,它帮助我思考Haskell提供的各种类型类.
注意:它正在更新到第二版,但第一版仍然具有相关性和信息性.