haskell - 在 Haskell 中使用 2 个以上的参数进行柯里化
问题描述
我开始学习 Haskell,所以我也需要了解柯里化(这也是我第一次看到这种技术)。我想我知道它在某些情况下是如何工作的,其中 currification 只“消除”了其中一个参数。就像在下一个示例中,我试图计算 4 个数字的乘积。这是未经处理的函数:
prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
这是咖喱函数:
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
但我不明白我怎么能继续这种动态,例如只用两个参数做同样的函数等等:
prod'' :: Integer->Integer->Integer->Integer->Integer
prod'' x y =
解决方案
这是未经处理的函数:
prod :: Integer -> Integer -> Integer -> Integer -> Integer prod x y z t = x * y * z * t
这已经是一个柯里化函数。事实上,Haskell 中的所有函数都是自动柯里化的。实际上,您在这里编写了一个如下所示的函数:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
Haskell 将因此生成一个如下所示的函数:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod = \x -> (\y -> (\z -> (\t -> x * y * z * t)))
事实上,我们可以例如生成这样的函数:
prod2 = prod 2
这将具有类型:
prod2 :: Integer -> (Integer -> (Integer -> Integer))
prod2 = prod 2
我们可以继续:
prod2_4 :: Integer -> (Integer -> Integer)
prod2_4 = prod2 4
最终:
prod2_4_6 :: Integer -> Integer
prod2_4_6 = prod2_4 6
编辑
具有以下功能的功能prod'
:
prod'' x y = (*) ((*) (x*y))
因为这意味着你乘(*) (x*y)
以下一个参数。而是(*) (x*y)
一个函数。您只能将数字相乘。严格来说,您可以制作函数编号。但是 Haskell 编译器因此抱怨:
Prelude> prod'' x y = (*) ((*) (x*y))
<interactive>:1:1: error:
• Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
prod'' :: forall a.
(Num (a -> a), Num a) =>
a -> a -> (a -> a) -> a -> a
因此,它表示您在这里的目标是以函数a -> a
作为第一个操作数来执行操作,但该函数不是类型类的实例Num
。
推荐阅读
- android - 如何使密码重置链接功能仅限于非第三方身份验证服务提供商创建的帐户
- python - TemplateDoesNotExist 在 /student/student_form/
- c# - ASP.NET MVC 5 RegisterView - 如何实现下拉列表
- api-platform.com - 模式生成器:强制字段基数会生成错误的 ORM 基数
- matplotlib - “savefig() 接受 2 个位置参数,但给出了 3 个”:如何仅传递图形的前 2 个位置参数?
- android - Android Hilt、Retrofit2 和属性文件问题
- css - Z-index 在绝对和相对元素之间不能按预期工作
- swift - 从主要异步 SwiftUI 执行代码行
- python - 如何处理“ValueError: ('max() arg 是一个空序列”
- c - 在 x86-64、skylake 上以可重启序列优化 percpu 2 级位向量