为什么我需要在Haskell中使用'neg square 4.2'的大括号?

时间:2014-02-24 10:01:47

标签: haskell

我目前正在使用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应用于结果。

但显然存在问题。两个案例中有什么问题?

3 个答案:

答案 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)

您可以在http://www.haskell.org/tutorial/functions.html

了解更多相关信息

答案 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 因此,当您使用negsquare撰写时,它会变为neg . square :: Num c => c -> c,现在只需要一个参数。如果您尝试立即将42应用于neg . square,则应用于4.4的{​​{1}}应用优先于squareneg的构成}应用于square(因为函数应用程序是左关联的)并将产生类型错误。