Considering Haskell has currying functions, we can do this:
foo a b = a + b -- equivalent to `foo a = \b -> a + b`
foo 1 -- ok, returns `\b -> 1 + b`
foo 1 2 -- ok, returns 3
Declaring the function returning a lambda, just like in the comment, works just fine as well.
But when I compose these functions, like this:
foo a b = a + b
bar x = x * x
bar . foo 1 -- ok, returns a lambda
bar . foo 1 2 -- wrong, I need to write `(bar . foo 1) 2`
Then it results in an error.
The question is: why are the parentheses around the function composition necessary?
Let's assume that you've define the following in GHCi:
λ> let foo a b = a + b
λ> let bar x = x * x
Based on some of your follow-up comments, it seems that you believe
bar . foo 1 2
to be equivalent to
(bar . foo 1) 2
However, remember that function application (space) has higher precedence than the composition operator (.); therefore
bar . foo 1 2
is really equivalent to
bar . ((foo 1) 2)
Now, let's look at the types:
. has type (b -> c) -> (a -> b) -> a -> c; its two arguments are functions (that can be composed).bar has type Num a => a -> a, and is therefore compatible with the type (b -> c) of the first argument of ..foo 1 2 has type Num a => a; it's a (polymorphic) numeric constant, not a function, and is therefore not compatible with the type (a -> b) of the second argument of ..That's why you're getting a type error in bar . foo 1 2. What you can do, though, is
bar $ foo 1 2
because the $ operator has type (a -> b) -> a -> b. See Haskell: difference between . (dot) and $ (dollar sign)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With