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
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