shimmer
shimmer

Reputation: 81

Haskell Pattern matching in let on function return vs function arguments

As a beginner at Haskell I've found it difficult to visually recognize some examples of pattern matching.

It seems that in let bindings sometimes the pattern matching occurs on the lhs when a function is called and the values are bound to variables in the equation on the rhs like in the following code example:

let boot x y z = x * y + z in boot 3 4 2

Sometimes however a function will be run in the rhs and the return values of that function will be bound to values in the lhs of the equation as in the definition of the State Monad from "Learn you a Haskell":

instance Monad (State s) where  
    return x = State $ \s -> (x,s)  
    (State h) >>= f = State $ \s -> let (a, newState) = h s  
                                        (State g) = f a  
                                    in  g newState 

where the function h is run with the lambda argument s and the return values are bound to (a, newState).

To a new Haskell programmer, this is slightly confusing. I could imagine a scenario where you might have:

let f a b = g c d in ...

where the function g would return a function and two arguments as it's return values. In this case would the "f a b" need to be wrapped in parenthesis for the pattern match to occur? I'm trying to find a definitive explanation of how the pattern matching occurs.

I have read most of "Learn You A Haskell For Great Good", as well as snippets from "Real World Haskell" and "A Gentle Introduction to Haskell" and I have not found a clear explanation of how to determine if the pattern matching should be occuring on arguments to a function or on the return values of a function. Any help in clearing this up would be appreciated.

Upvotes: 5

Views: 957

Answers (1)

melpomene
melpomene

Reputation: 85827

I believe you're stumbling over the difference between function and pattern bindings.

In short, if you have something like "variable pat1 pat2 ... =" (where pat1 pat2 ... are one or more patterns), it's a function binding; otherwise it's a pattern binding. In the most simple case, x y z = ..., a function binding is just syntactic sugar for a lambda: x = \y z -> ....

If it starts with a (, it's not a variable, so the whole thing must be a pattern binding. But even without parens State x is still a pattern binding because State is not a variable (it starts with an uppercase letter so it must be a constructor).

Upvotes: 6

Related Questions