我目前正在使用99 questions学习Haskell,我在一个解决方案中看到.
。它似乎是数学中已知的常用函数组合:
f ∘ g
我想确保我已正确理解并创建了这个示例:
square x = x*x
neg x = (-1)*x
main = do
-- let result = neg (square 4.1) -- works
-- let result = square (neg 4.2) -- works
-- let result = neg $ square 4.3 -- works
let result = neg square 4.4 -- doesn't work
-- let result = neg . square 4.5 -- doesn't work
-- let result = neg . square $ 4.6 -- works
-- let result = neg square $ 4.7 -- does not work
print result
可悲的是,只有前三行有效(至少它们按预期工作)。
为什么我需要在较低的两种情况下使用牙套?我认为你不需要它们,因为我认为通过点,neg
得到square
作为输入。所以它仍然是一个功能,看起来像
(-1)*x*(-1)*x
然后将4.4放在那里x
,这应该没问题。
我认为如果没有点,Haskell首先将square
应用于4.5,然后将neg
应用于结果。
但显然存在问题。两个案例中有什么问题?
答案 0 :(得分:6)
函数应用程序()具有Haskell中所有运算符的最高优先级,所以
neg . square 4.5
表示neg . (square 4.5)
,这没有意义,因为(square 4.5)
是一个数字,而不是一个函数,所以你不能用neg
来组合它。 / p>
而neg square $ 4.7
表示(neg square) $ 4.7
,但square
不是数字,而是neg
。
答案 1 :(得分:1)
在Haskell中,函数应用程序是左关联的,因此a b c d
表示((a b) c) d)
。
答案 2 :(得分:0)
neg
的类型是
neg:: Num a => a -> a
当你只需要一个时,你试图将两个参数应用于neg。
(.)
是函数组合,而不是连接。
let result = neg . square 4.5
应为let result = neg . square $ 4.5
在neg . square
的情况下,你正在组成两个函数。
(.)
的类型为(b -> c) -> (a -> c) -> a -> c
因此,当您使用neg
和square
撰写时,它会变为neg . square :: Num c => c -> c
,现在只需要一个参数。如果您尝试立即将42
应用于neg . square
,则应用于4.4
的{{1}}应用优先于square
和neg
的构成}应用于square
(因为函数应用程序是左关联的)并将产生类型错误。