问题描述:

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
相关阅读:
Top