Number of arguments and point-free in Haskell [duplicate]

爱⌒轻易说出口 提交于 2019-12-06 17:30:31

问题


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? :'(


回答1:


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




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!