簡體   English   中英

了解haskell monads的范圍

[英]Understanding scoping with haskell monads

我試圖理解范圍在do塊中是如何工作的。

如果我有以下代碼:

l = [1, 2, 3]
m = [1, 2]

然后這工作正常

res = do
    a <- l
    b <- m
    return (a, b)

並返回ml的笛卡爾積。

為了理解范圍,我試圖以不同的形式重寫它(沒有做塊)

我知道塊只是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM