问题描述:

I'm learning Haskell now and I'm trying to play around with function composition.

I wrote two functions.

`let func1 x y = x + y`

`let func2 t = t*2`

However, when I try to compose these two functions,

`func2 . func1 1 2`

I am expecting to get 6.

Instead, I get this error:

`No instance for (Num (a -> b))`

arising from a use of `func1' at <interactive>:1:8-16

Possible fix: add an instance declaration for (Num (a -> b))

In the second argument of `(.)', namely `func1 1 2'

In the expression: func2 . func1 1 2

In the definition of `it': it = func2 . func1 1 2

Can someone explain why this is not working?

Function application has precedence over any operators, so your composition is parsed as `func2 . (func1 1 2)`

. That is, your code tries to compose the number that's the result of `func1 1 2`

as if it was a function. Note that `(func2 . func1) 1 2`

doesn't work either, as `(.)`

only works with unary functions.

You *could* use `(func2 . func1 1) 2`

, or use `(.)`

multiple times in ways that I'm not very comfortable with personally, to tell the truth. But it's probably better to not use composition at all in this specific case: `func2 $ func1 1 2`

does the same thing with less clutter.

Due to a lucky mistake (distributive law), you can do this with `Data.Function.on`

```
import Data.Function
func1 x y = x + y
func2 t = t*2
func3 = func1 `on` func2
-- or just func3 = (+) `on` (2*)
```

In general though, you should just use `$`

for this sort of thing, since that's what you're doing, function application. This isn't really a job for compose, so you're trying to jam a square peg into a round hole if you use composition.

What you're trying to do is not function composition: You're trying to apply `func1 1 2`

to `func2`

, that's what the `$`

operator is for.

```
func2 $ func1 1 2
```