2011-07-09 119 views
9

通過工作了解您一個Haskell偉大的好,筆者走過的幾個不同的庫函數的實現對高階函數的節。當來到filter'(標準庫函數filter的重新實現)的定義,我認爲很明顯的事情是這樣的:遞歸或列表理解?

filter' f xs = [x | x <- xs, f x] 

但筆者給出以下較長,遞歸定義:

filter' _ [] = [] 
filter' p (x:xs) 
    | p x  = x : filter' p xs 
    | otherwise = filter' p xs 

兩個定義都做同樣的事情。這有什麼理由嗎?遞歸定義是否更高性能?對於Haskell來說它更習慣嗎?還有別的嗎?

+1

'filter''也可以在高階函數'foldr'方面寫成'濾波器的」 p = foldr相似(\ X YS - >如果PX則x:YS別的YS)[]',雖然這將是一個使用高階函數的好例子,而不是如何從頭開始構建一個函數。 – hammar

+0

如果您對如何解除它們感興趣,請參見[Haskell 2010>表達式>列表解析](http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11)。 –

回答

13

這可能是因爲該名單的理解僅僅是語法糖,原則上被翻譯成遞歸形式。

如果作者的一點是要說明如何在功能實現,使用列表解析快捷方式並沒有真正做到這一點 - 它顯示了另一種方式來表達的解決方案,但不是一個真正的功能實現。

總之,它展示瞭如何從一組基本構建塊的相當小的實現。

這是一個猜測,但 - 我還沒有看過該教程自己。

8

列表理解對於一個映射和一個操作中的過濾器來說是非常多的糖;雖然它可能在後端使用concatMap。通常使用更高抽象的東西來實現更低抽象的東西就是作弊。

+0

你不能用地圖和過濾器來實現列表解析,你真的需要concatMap。 – augustss

+1

@augustss你爲什麼覺得我特別提到它使用concatMap?我得到的是過濾器基本上是concatMap的一部分。 – alternative

+0

「可能使用」聽起來不像「必須使用」。 :) – augustss