[英]Understanding scoping with haskell monads
我试图理解范围在do块中是如何工作的。
如果我有以下代码:
l = [1, 2, 3]
m = [1, 2]
然后这工作正常
res = do
a <- l
b <- m
return (a, b)
并返回m
和l
的笛卡尔积。
为了理解范围,我试图以不同的形式重写它(没有做块)
我知道块只是monadic操作的语法糖,所以我试图“unsugar”它并使用它并想出了这个:
res = l >>= (\a -> m) >>= (\b -> return (a, b))
奇怪的是我得到这个错误Not in scope: 'a'
。
任何人都可以告诉我我做错了什么,可能,范围如何工作,因为看起来像魔术,do块中的return
能够访问?
非常感谢你
问题是代码中lambda的范围不太正确。 它应该一直延伸到表达式的末尾,而不仅仅是小计算。 你的代码应该是desugar
l >>= (\a -> m >>= (\b -> return (a, b))
你可以顺便放下括号,这样可以让它更愉快。
l >>= \a -> m >>= \b -> return (a, b)
但这种模糊了意义。 如果你想要明确,我们可以转换为前缀表示法并说
bind a f = a >>= f
bind l (\a -> bind m (\b -> return (a, b))
也许剥离一些操作员的糖有帮助。
注意>> ='嵌套在 lambda 内部 ,而不是它周围。 这确保a
范围仍然存在。 事实上,这种嵌套是手工写出来的一点点痛苦,这是写法的推动力的一部分:)
问题出在你的括号上。 你写
res = l >>= (\a -> m) >>= (\b -> return (a, b))
但你需要的是
res = l >>= (\a -> m >>= (\b -> return (a, b)))
也可以写
res = l >>= \a -> m >>= \b -> return (a, b)
您结束了lambda表达式绑定a
过早,然后试图用a
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.