简体   繁体   中英

Is it possible to use functions in Haskell parameters?

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?

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

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.

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)    

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.

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 (fx) 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

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) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM