[英]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.