2011-10-04 79 views
6

我現在正在與Haskell玩耍,因此偶然發現了列表理解功能。 當然,我會用一個封閉做這樣的事情:Haskell中的閉包和列表解析

Prelude> [x|x<-[1..7],x>4] -- list comprehension 
[5,6,7] 
Prelude> filter (\x->x>4) [1..7] -- closure 
[5,6,7] 

我仍然不覺得這種語言,所以該方法將一個Haskell程序員去? 這兩種解決方案有什麼區別?

+1

而不是「封閉」,你的意思是「lambda表達式」又名「匿名函數」 – newacct

+0

@newacct:封閉是我在HaskellWiki中找到的術語:[鏈接] http://www.haskell.org/haskellwiki/Closure 還是他們描述了不同的東西? – Zakum

+1

「閉包」沒有描述語法,而是一個關於函數從定義範圍捕獲自由變量的能力的概念。該鏈接演示了一個特定函數如何關閉一個自由變量的例子;它與所使用的語法無關。 – newacct

回答

10

慣用哈斯克爾是filter (> 4) [1..7]

注意,你是不是捕捉任何詞彙範圍,在你關閉,並而是利用分段式操作的。也就是說,您想要部分應用>,哪些運營商部門會立即給您。列表理解有時候很有吸引力,但是通常的看法是它們不像通常的高階函數(比較複雜的成分「尺度」)那麼好。這種風格決定當然主要是主觀的,所以YMMV。

+1

這也允許功能組合,而列表理解則不允許。 – ivanm

1

如果元素有些複雜,需要通過模式匹配來過濾元素,或者映射部分對於lambda抽象來說太複雜,應該是短的(或者我覺得),或者if必須處理嵌套列表。在後一種情況下,列表理解通常比替代方案(對我來說)更具可讀性。

例如像:

[ (f b, (g . fst) a) | (Just a, Right bs) <- somelist, a `notElem` bs, (_, b) <- bs ] 

但對於你的例子中,區域(>4)是寫(\a -> a > 4)一個非常好的方式,因爲你只使用它進行過濾,大多數人寧願安東尼的解決方案。