Factorial Creation in Haskell

80 Views Asked by At

I was recently reading a paper where the defintion for a factorial is given as such:

fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n

I implemented the program from the paper as below:

fac :: Integer -> Integer
fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n

I then tried to use Num a as an alternative, thinking the type signature might be the problem.

fac :: Num a => a -> a
fac 0 = 1
fac (n + 1) = (n + 1) ∗ fac n

But when I try to compile this using GHCi, for both of the problems I get the following error:

Factorial.hs:5:6: error: Parse error in pattern: n + 1
  |
5 | fac (n + 1) = (n + 1) ∗ fac n

Can anyone explain why the error occurs?

Thanks

I've tried implementing the code in the paper as shown. I also added the type signature not in the paper. I then tried a less constraining type in the type signature. All with the same error.

1

There are 1 best solutions below

0
jpmarinier On

By default, n+1 is currently not a proper Haskell pattern. In the past, Haskell did have such "n+k" patterns, and your document has probably been written when n+k patterns were supported.

The feature can still be used with recent compilers, provided the NPlusKPatterns language extension is explicitly switched on. For example, the following code works as expected:

{-#  LANGUAGE  NPlusKPatterns  #-}

fac :: Integral a => a -> a
fac 0 = 1
fac (n + 1) = (n + 1) * (fac n)


main :: IO()
main = do
   putStrLn $ "Factorial of 7 is: " ++ (show $ fac 7)

A significant part of the Haskell community had come to regard n+k patterns as a misfeature, hence their removal from the language when the Haskell 2010 standard came out.

So the proper modern syntax is just:

fac :: Integral a => a -> a
fac 0 = 1
fac n = n * (fac (n-1))

Related SO question: see what-are-nk-patterns-and-why-are-they-banned-from-haskell-2010