With multiple pattern-matching, different numbers of arguments are impossible, even with point-free!
foo True b = b + 2
foo _ = id
doesn't work for example. But
foo True = (+2)
foo _ = id
does. Sometimes we can use point-free only in one part of the function, so...
Why? Is it too hard for GHC? :'(
Why? Is it too hard for GHC?
No. It is not at all too hard for GHC. Actually, this is the fault of the Haskell Report.
See: Haskell Report 2010 > Declarations and Bindings > Function bindings
A function binding binds a variable to a function value. The general form of a function binding for variable x is:
x p11 … p1k match1
…
x pn1 … pnk matchn[...blah blah...]
Translation: The general binding form for functions is semantically equivalent to the equation (i.e. simple pattern binding):
x = \ x1 … xk -> case (x1, …, xk) of
(p11, …, p1k) match1
…
(pn1, …, pnk) matchn
where the xi are new identifiers.
(emphasis mine)
While function definitions are semantically equivalent to a lambda & case expression, they are not necessarily compiled that way, as Mihai suggests.
The thing is, the Haskell report defines function declarations such that they must have the same number of inputs on the left-hand side of the equation. This is made clear by the fact that k
remains the same on both the 1st and the nth function declaration lines (and by implication, all lines in-between). This is the reason for the restriction; it has nothing to do with GHC's implementation details.
tl;dr
The choice not to allow it is just a matter of style. – augustss
Each function equation must have the same number of arguments. This is why your first example fails.
To fix it, use
foo True b = b + 2
foo _ x = id x
As you see, both equations have the same number of arguments.
Multiple equations involving pattern matching are translated into case expressions. In your case foo
gets translated roughly as
foo a b = case a of
True -> b + 2
_ -> id x
Both (all) branches of the case
must have the same type, thus you first example which would be translated as
foo a b = case a of
True -> b + 2
_ -> id
is wrong because the branches have different types.
Of course, this is hand waving, the actual things happening behind the scenes are more complicated
来源:https://stackoverflow.com/questions/11487171/number-of-arguments-and-point-free-in-haskell