2010-09-20 44 views
50

當讀取Wikipedia's entry on Haskell 2010我偶然發現了這一點:什麼是「n + k模式」,爲什麼他們從Haskell 2010中被禁止?

-- using only prefix notation and n+k-patterns (no longer allowed in Haskell 2010) 
factorial 0 = 1 
factorial (n+1) = (*) (n+1) (factorial n) 

他們是什麼意思的 「N + K模式」?我想這是第二行,但我不明白它可能有什麼問題。任何人都可以解釋那裏有什麼問題嗎?爲什麼Haskell 2010中不允許使用這些n + k模式?

+0

暗示可能是爲什麼* n + k模式檢查出這個優秀的博客文章:http://blog.sigfpe.com/2007/07/data-and-codata.html – jberryman 2011-05-05 00:36:43

+6

對於還在想要使用n + k模式(我在看着你,Erik Meijer),有'-XNPlusKPatterns'或'{ - #LANGUAGE NPlusKPatterns# - }' – tlo 2014-11-20 22:23:00

回答

58

什麼是n + k模式?採取甘德在此:

$ ghci 
GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 
Prelude> let f 0 = 0 ; f (n+5) = n 
Prelude> :t f 
f :: (Integral t) => t -> t 
Prelude> f 0 
0 
Prelude> f 1 
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f 

Prelude> f 2 
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f 

Prelude> f 3 
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f 

Prelude> f 4 
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f 

Prelude> f 5 
0 
Prelude> f 6 
1 

,他們基本上模式匹配的一個極其特殊的情況下,只對數字有效,哪些......好吧,我們只是禮貌並稱之爲「意想不到的事情」那些數字。

這裏我有一個功能f它有兩個子句。第一個子句匹配0並且只匹配0。第二個子句匹配值爲5或更大的Integral類型的任何值。綁定名稱(在本例中爲n)的值等於您在-5中傳遞的數字。至於爲什麼他們已從Haskell 2010中刪除,我希望只需稍加思考即可看到原因。 (提示:考慮到「最小驚訝的原則」,以及它如何可能會或可能不會在這裏適用。)


編輯補充:

一個自然的問題現在出現的這些結構被禁止是「你用什麼來代替它們?」

$ ghci 
GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 
Prelude> let f 0 = 0 ; f n | n >= 5 = n - 5 
Prelude> :t f 
f :: (Num t, Ord t) => t -> t 
Prelude> f 0 
0 
Prelude> f 1 
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f 

Prelude> f 2 
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f 

Prelude> f 3 
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f 

Prelude> f 4 
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f 

Prelude> f 5 
0 
Prelude> f 6 
1 

你會從類型聲明中注意到這些並不完全相等,但是使用警衛是「足夠平等」的。在表達式中使用n-5可能會在任何使用多個地方的代碼中變得單調乏味且容易出錯。答案將是沿着這一線路使用where條款:

Prelude> let f 0 = 0 ; f n | n >= 5 = n' where n' = n - 5 
Prelude> :t f 
f :: (Num t, Ord t) => t -> t 
Prelude> f 0 
0 
Prelude> f 5 
0 
Prelude> f 6 
1 

where子句允許您使用在多個地方計算表達式,而不鍵入錯誤的風險。在函數定義中的兩個不同位置編輯邊界值(在這種情況下爲5)仍然存在煩惱,但是我個人認爲這對於認知理解的增加而言是一個小的代價。


進一步編輯補充:

如果你喜歡let表達了where條款,這是一種替代方案:

Prelude> let f 0 = 0 ; f n | n >= 5 = let n' = n - 5 in n' 
Prelude> :t f 
f :: (Num t, Ord t) => t -> t 
Prelude> f 0 
0 
Prelude> f 5 
0 

就是這樣。我現在真的做完了。

+1

+2(是的兩個)我的投票是這樣的回答是因爲它以很好的方式解釋了'它是什麼'以及'它爲什麼'被完全覆蓋。 – 2010-09-20 04:46:06

+0

太棒了!謝謝!! – 2010-09-20 05:01:38

+0

很好的答案!我對Haskell很新,所以我的下一個問題是:爲什麼類型檢查器允許這種模式,並且至少不會發出警告?在這種情況下,它必須知道該代碼缺少一些情況。 – futtetennista 2014-11-30 19:22:58

4

trinithis提供的鏈接是正確的; Haskell規範中不再包含n + k個模式。

有關n + k圖案的更多背景知識,請滾動瀏覽本頁面的3/5頁pattern matching或查看此短片post

相關問題