什麼是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
就是這樣。我現在真的做完了。
暗示可能是爲什麼* n + k模式檢查出這個優秀的博客文章:http://blog.sigfpe.com/2007/07/data-and-codata.html – jberryman 2011-05-05 00:36:43
對於還在想要使用n + k模式(我在看着你,Erik Meijer),有'-XNPlusKPatterns'或'{ - #LANGUAGE NPlusKPatterns# - }' – tlo 2014-11-20 22:23:00