好,你的體面的開始,但重要的是要注意,你沒有采取最「Haskell」的方法。
讓我告訴你一些不同的方法解決這個問題:
方法1:遞歸函數
首先,我們可以寫一個遞歸函數(如你)來解決這個。
要做到這一點,我們首先容納用於一個基本情況(一個不會,一般情況下,允許一個無限循環)。這應該工作:
remove [] _ = []
這僅僅是說,如果我們從一個空的列表中刪除元素,我們結束了一個空列表。就這麼簡單。 _
意味着我們不在乎x
是什麼值。現在
我們必須定義其他案件。對於這一點,我會用後衛(我敢肯定有其他的辦法,基本情況還增加了完成):
remove [] _ = []
remove (x:xs) y
| x > y = remove xs y
| otherwise = x : remove xs y
所以,第一行(remove (x:xs) y
)是說,我們的函數將採取列表(其中x
是磁頭/第一值和xs
是其餘部分)。
第二行是說,如果x
大於y
,請考慮其餘元素,並且我們不認爲x
是我們最終解決方案的一部分。
第三行(otherwise
捕獲所有的情況下,如果命中,就像if/elseif/else
在if/elseif/else
其他語言的條件塊中的else
)。如果我們到了這一點,我們知道這是不正確的x > y
所以我們認爲我們的價值觀(xs
)的其餘部分,我們包括x
,但我們與x
做了現在。
現在,這種方法工作體面,但有一個簡單的辦法:
方法2:列表綜合
使用list comprehensions我們可以建立一個非常簡單的,功能強大的解決方案:
remove xs y = [x | x <- xs, not (x > y)]
如果你曾經學過set-theory(特別是set-builder notation),你應該看起來很奇怪。我們來看看每個部分的含義。
[...]
- 東西方括號只是意味着我們正在建設一個列表
x |...
- 意味着我們的列表將包含x
S,從而使(該|
手段 「使得」)...
x <- xs,
- x
是xs
(逗號表示 「和」)的元素,...
not (y > x)
- 這是不正確的y
大於x
正如你所看到的,第二種方法幾乎完全模仿你的問題的描述。這確實是Haskell的力量,單詞和抽象幾乎都直接映射到Haskell代碼中。
方法3:使用filter
由於下面的評論的狀態的第三替代方案將是把它定義爲這樣:
remove y = filter (<=y)
當過濾器將只保留是小於或等於的元素到y。 (感謝Daniel Wagner提供這種方法)。
你得到了無限循環,因爲'然後刪除(drop 0 l1)x'你在同一個列表上重複出現,'drop'的第一個參數表示要刪除多少個元素,並且您錯誤地輸入了'drop 0'而不是你需要「降1」。 – 2013-04-10 10:20:17