2012-02-24 38 views
4

我已經看到了幾個在參數中使用函數的Haskell代碼的例子,但我永遠無法讓它爲我工作。是否可以在Haskell參數中使用函數?

例如:

-- Compute the nth number of the Fibonacci Sequence 
    fib 0 = 1 
    fib 1 = 1 
    fib (n + 2) = fib (n + 1) + fib n 

當我嘗試這一點,我得到這個錯誤:

Parse error in pattern: n + 2 

這只是一個壞榜樣?或者我必須做一些特殊的事情來完成這項工作?

+0

也許這是有趣的? http://stackoverflow.com/questions/3748592/what-are-nk-patterns-and-why-are-they-banned-from-haskell-2010 – gspr 2012-02-24 15:50:42

+3

這些所謂的(n + k)模式從Haskell被禁止前一段時間。將第三行替換爲:'fib n = fib(n - 1)+ fib(n - 2)'。 – Vitus 2012-02-24 15:51:22

+0

注意:還有一種方法可以在等式左側看到函數調用:[ViewPatterns](http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns)。我很驚訝他們不是更常見。 – 2012-02-24 17:28:59

回答

1

由於(+)是一個函數,因此無法對它進行模式匹配。要做你想做的事,你需要修改第三行:fib n = fib (n - 1) + fib (n - 2)

2

我會盡力幫忙,是一個總的新手在Haskell。

我認爲問題在於你無法匹配(n + 2)。 從邏輯的角度來看,任何參數「n」都不會匹配「n + 2」,所以你的第三條規則永遠不會被選中進行評估。

您可以重寫它,就像邁克爾說,:

fib n = fib (n - 1) + fib (n - 2) 

或使用警衛定義一個函數整個fibonnaci,是這樣的:

fibonacci :: Integer -> Integer 
fibonacci n 
| n == 0 = 0 
| (n == 1 || n == 2) = 1 
| otherwise = fibonacci(n-1) + fibonacci(n-2)  
+0

我認爲你的意思是*警衛*,而不是你最後一個例子中的模式匹配。 – gspr 2012-02-24 15:56:56

+0

的確,我的確像我說的...一個新手一樣,最終我濫用了這種語言。謝謝。 – pcalcao 2012-02-24 15:58:02

2

模式匹配器,僅限於構造函數。因此,儘管可以匹配(:)(列表constrcutor)或LeftRight(構造函數Either)等函數的參數,但不能匹配算術表達式。

2

我認爲fib (n+2) = ...表示法不起作用,是一個語法錯誤。您可以使用「正則表達式」的風格匹配的paramters,如列表或元組:

foo (x:xs) = ... 

其中x是列表的頭部和XS的列表的其餘部分或

foo (x:[]) = 

其匹配如果列表只剩下一個元素並存儲在x中。即使是複雜的匹配,如

foo ((n,(x:xs)):rg) = ... 

是可能的。 haskell中的函數定義是一個複雜的主題,可以使用很多不同的樣式。

另一種可能性是使用「切換情況下的」方案的:

foo f x | (f x) = [x] 
foo _ _ = [] 

在這種情況下,元素「X」被包裹在一個列表中,如果條件(f x)是真實的。在其他情況下,f和x參數不感興趣,並返回一個空列表。

解決您的問題,我不認爲任何一個都適用,但爲什麼不以追趕其餘參數值函數定義拋出,如:

fib n = (fib (n - 1)) + (fib (n - 2)) 

希望這有助於,

奧利弗

3

正如托馬斯所說,你可以使用視圖模式來實現:

{-# LANGUAGE ViewPatterns #-} 

fib 0 = 1 
fib 1 = 1 
fib ((subtract 2) -> n) = fib (n + 1) + fib n 

由於在這種情況下-含糊不清,您需要改用subtract函數。

相關問題