haskell - 如何解释多个参数的函数?
问题描述
给定以下功能
multThree :: (Num a) => a -> a -> a -> a
multThree x y z = x * y * z
以及它的描述:
当我们做
multThree 3 5 9
or时会发生什么((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
本段所述功能的正确解释吗?
解决方案
你很接近,但你错过了一个关键点。((3*y*z)5)9
不是一个有效的表达式。特别是,虽然multThree
inmultThree 9
是一个函数,但3*y*z
(你替换的东西multThree
)不再是一个函数。(另请注意,y
andz
是在没有定义的情况下使用的)。为了解决这个问题,我们将重写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
.
推荐阅读
- arrays - 对包含 8 个元素的数组进行排序的最快方法是什么?
- python - 在 Django 中替换生成密钥的随机部分
- javascript - 查询对firebase中另一个对象内的日期进行排序
- java - gradle集成测试不起作用,单元测试运行两次
- node.js - NPM 构建因 UglifyJs 错误而失败 - 意外令牌:名称(上下文)
- numpy - 如何将数据集拆分为训练集、测试集和交叉验证集?
- express - 未定义的 jwt 令牌反应/表达
- unity3d - 无法通过 Autodoesk forge API 创建场景
- c - 如何使用循环展开和重新关联?
- arrays - 如何提取@_的子集?