首页 > 解决方案 > 如何解释多个参数的函数?

问题描述

给定以下功能

multThree :: (Num a) => a -> a -> a -> a  
multThree x y z = x * y * z  

以及它的描述:

当我们做multThree 3 5 9or时会发生什么((multThree 3) 5) 9?首先,将 3 应用于multThree,因为它们用空格分隔。这将创建一个函数,该函数接受一个参数并返回一个函数。然后将 5 应用于该函数,这将创建一个函数,该函数将接受一个参数并将其乘以 15。 9 应用于该函数,结果为 135 或其他值。请记住,此函数的类型也可以写为multThree :: (Num a) => a -> (a -> (a -> a)).

我将其解释如下,并希望确保这是正确的:

((multThree 3) 5) 9 =
((3*y*z)5)9 =
(15*z)9 =
15*9
= 135

这是对multThree本段所述功能的正确解释吗?

标签: haskell

解决方案


你很接近,但你错过了一个关键点。((3*y*z)5)9不是一个有效的表达式。特别是,虽然multThreeinmultThree 9是一个函数,但3*y*z(你替换的东西multThree)不再是一个函数。(另请注意,yandz是在没有定义的情况下使用的)。为了解决这个问题,我们将重写multThree

multThree = (\x -> (\y -> (\z -> x * y * z)))
-- or dropping all the unnecessary brackets
multThree = \x -> \y -> \z -> x * y * z

现在您可以替换并解决所有问题:

multThree 3 5 9
= (\x -> \y -> \z -> x * y * z) 3 5 9
= (\y -> \z -> 3 * y * z) 5 9
= (\z -> 3 * 5 * z) 9
= 3 * 5 * 9

这也可能引发关于乘法运算符的求值顺序的另一个问题(*)。在我们的例子(*)中是左关联的:

Prelude> :info (*)
class Num a where
  ...
  (*) :: a -> a -> a
  ...
    -- Defined in `GHC.Num'
infixl 7 *

也就是说,您3 * 5 * 9实际上是(3 * 5) * 9.


推荐阅读