我现在正在学习Haskell,我正在尝试使用函数组合。
我写了两个函数。
let func1 x y = x + y
let func2 t = t*2
但是,当我尝试编写这两个函数时,
func2 . func1 1 2
我期待得到6.
相反,我收到了这个错误:
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
有人可以解释为什么这不起作用吗?
答案 0 :(得分:4)
函数应用程序优先于任何运算符,因此您的组合被解析为func2 . (func1 1 2)
。也就是说,您的代码会尝试将func1 1 2
的结果编号组成,就像它是一个函数一样。请注意,(func2 . func1) 1 2
也不起作用,因为(.)
仅适用于一元函数。
你可以 使用(func2 . func1 1) 2
,或者以我个人不太熟悉的方式多次使用(.)
来说实话。但在这种特殊情况下,根本不使用构图可能会更好:func2 $ func1 1 2
做同样的事情而不会出现混乱。
答案 1 :(得分:3)
由于幸运的错误(分配法),您可以使用Data.Function.on
import Data.Function
func1 x y = x + y
func2 t = t*2
func3 = func1 `on` func2
-- or just func3 = (+) `on` (2*)
一般来说,你应该只使用$
来做这类事情,因为那就是你正在做的事情,功能应用。这对于作曲来说并不是一个真正的工作,所以如果你使用合成,你就试图将方形钉子塞进一个圆孔中。
答案 2 :(得分:1)
您尝试做的不是功能组合:您尝试将func1 1 2
应用于func2
,这就是$
运算符的用途。
func2 $ func1 1 2