4

I have seen a few examples of Haskell code that use functions in parameters, but I can never get it to work for me.

example:

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

When I try this, it I get this error:

    Parse error in pattern: n + 2

Is this just a bad example? Or do I have to do something special to make this work?

3
  • Maybe this is of interest? stackoverflow.com/questions/3748592/… Commented Feb 24, 2012 at 15:50
  • 3
    These so-called (n + k) patterns were banned from Haskell some time ago. Replace third line with: fib n = fib (n - 1) + fib (n - 2). Commented Feb 24, 2012 at 15:51
  • NB There is another way you can see function calls on the left hand side of an equation: ViewPatterns. I'm rather surprised they aren't more common. Commented Feb 24, 2012 at 17:28

6 Answers 6

13

What you have seen is a special type of pattern matching called "n+k pattern", which was removed from Haskell 2010. See What are "n+k patterns" and why are they banned from Haskell 2010? and http://hackage.haskell.org/trac/haskell-prime/wiki/RemoveNPlusK

Sign up to request clarification or add additional context in comments.

Comments

3

As Thomas mentioned, you can use View Patterns to accomplish this:

{-# LANGUAGE ViewPatterns #-}

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

Due to the ambiguity of - in this case, you'll need to use the subtract function instead.

Comments

2

I'll try to help out, being a total newbie in Haskell.

I believe that the problem is that you can't match (n + 2). From a logical viewpoint, any argument "n" will never match "n+2", so your third rule would never be selected for evaluation.

You can either rewrite it, like Michael said, to:

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

or define the whole fibonnaci in a function using guards, something like:

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

2 Comments

I think you mean guards, not pattern matching in your last example.
Indeed I do, like a said... a newb, and I ended up abusing the language. Thank you.
2

The pattern matcher is limited to constructor functions. So while you can match the arguments of functions like (:) (the list constrcutor) or Left and Right (constructors of Either), you can't match arithmetic expressions.

Comments

2

I think the fib (n+2) = ... notation doesn't work and is a syntax error. You can use "regular expression" style matching for paramters, like lists or tuples:

foo (x:xs) = ...

where x is the head of the list and xs the remainder of the list or

foo (x:[]) = 

which is matched if the list only has one element left and that is stored in x. Even complex matches like

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

are possible. Function definitions in haskell is a complex theme and there are a lot of different styles which can be used.

Another possibility is the use of a "switch-case" scheme:

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

In this case, the element "x" is wrapped in a list if the condition (f x) is true. In the other cases, the f and x parameters aren't interesting and an empty list is returned.

To fix your problem, I don't think any of these are applicable, but why don't throw in a catch-remaining-parameter-values function definition, like:

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

Hope this helps,

Oliver

Comments

1

Since (+) is a function, you can't pattern match against it. To do what you wanted, you'd need to modify the third line to read: fib n = fib (n - 1) + fib (n - 2).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.