문제

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top