문제

Can someone explain me, why do these functions have different number of arguments and behavior, but the same type signature, yet they are both correct?

comp1 :: (a -> b) -> (b -> c) -> a -> c
comp1 f g = g.f

comp2 :: (a -> b) -> (b -> c) -> a -> c
comp2 f g x = g (f x)

also, why does comp2 has

comp2 :: (a -> b) -> (b -> c) -> a -> c

instead of something like

comp2 :: a -> (a -> b) -> (b -> c) -> a -> c

?

Thank you.

도움이 되었습니까?

해결책

comp2 f g x = g (f x)

is syntactic sugar for

comp2 = \f -> \g -> \x -> g (f x)

Similarly

comp1 f g = g.f

is sugar for

comp1 = \f -> \g -> g.f

The definition of . is:

f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion

So if we insert the definition into the desugared form of comp1, we get:

comp1 = \f -> \g -> \x -> g (f x)

This is exactly the same as the desugared form of comp2, so clearly the definitions are equivalent.

다른 팁

comp1 f g = g.f is written in point-free style (not referring to points, but to values). When you call comp1, there is implicitly a third parameter being passed to g.f, which is the composition of the two functions g and f: (g.f) x equals g (f x), i.e. g is passed the result of f x. No parameter x exists in comp1 because it's implicitly passed to the function. (You could think of comp1 as a partially applied or curried function if it makes you feel better.)

comp2's type asks for two functions, one from (a->b) and another (b->c), as well as a parameter of type a. There is no need to put an a -> in its signature.

The two functions are really equivalent; one simply uses some Haskell tricks to be more concise.

Currying. A multi-argument function in ML and Haskell, is just syntactic sugar for a one-argument function that returns a function; the function that it returns takes the remaining arguments.

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