What are n + k patterns and why are they banned in Haskell 2010?

When you read the Wikipedia entry on Haskell 2010 , I came across this:

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

What do they mean by "n + k patterns"? I assume this is the second line, but I do not understand what might be wrong. Can anyone explain what the problem is? Why are these n + k patterns more allowed in Haskell 2010?

+53
functional-programming haskell
Sep 20 '10 at 3:44
source share
2 answers

What are n + k patterns? Take a gander:

 $ 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> :tf 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 

Basically this is a special case of pattern matching that works only on numbers and which ... well, just be polite and call it "unexpected things" for these numbers.

Here I have a function f that has two sentences. The first sentence matches 0 and only 0 . The second sentence matches any Integral value whose value is 5 or greater. The associated name ( n , in this case) has a value equal to the number you passed minus 5. As to why they were removed from Haskell 2010, I hope you can now see the reason for thinking. (Hint: consider the principle of least surprise and how it may or may not apply here.)




Edited to add:

The natural question that now arises when these constructions are forbidden is "what do you use to replace them?"

 $ 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 ; fn | n >= 5 = n - 5 Prelude> :tf 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 

From type expressions, you will notice that they are not exactly equal, but the use of a guard is โ€œfairly equalโ€. Using the n-5 expression in an expression can become tedious and error prone in any code that uses it in multiple places. The answer will be to use the where clause in the lines:

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

The where clause allows you to use a computed expression in several places without the risk of typos. There is still the annoyance of having to edit the boundary value (5 in this case) in two separate places in the definition of the function, but personally I feel that this is a small price to pay for an increase in cognitive understanding.




Further edited to add:

If you prefer let expressions over where clauses, this is an alternative:

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

What is it. I really did it now.

+60
Sep 20 '10 at 4:22
source share

The link provided by trinithis is correct; N + k models are no longer included in the Haskell specification.

For more information on n + k models, generally scroll around 3/5 of the way down this page to match patterns or check out this short post .

+4
Sep 20 2018-10-10T00:
source share



All Articles