Haskell 我对可还原表达式(即redex)的理解是否正确?

Haskell 我对可还原表达式(即redex)的理解是否正确?,haskell,functional-programming,redex,Haskell,Functional Programming,Redex,Hutton在Haskell中编程时说: 一个表达式的函数形式应用于一个或多个参数,这些参数可以通过执行应用程序进行“缩减”,该表达式称为可缩减表达式,简称redex 是一个可约表达式,即redex 函数应用程序,其中函数不是另一个函数应用程序的结果 等价地,函数是函数名或lambda表达式的函数应用程序 以上两点是否回答了我在上一个问题?您也会问(在链接条目上)“mult(3)不是一个部分应用程序,所以它有意义吗?” 我想我已经回答了你之前的一个问题 否,mult的类型是(Int,Int)

Hutton在Haskell中编程时说:

一个表达式的函数形式应用于一个或多个参数,这些参数可以通过执行应用程序进行“缩减”,该表达式称为可缩减表达式,简称redex

是一个可约表达式,即redex

  • 函数应用程序,其中函数不是另一个函数应用程序的结果

  • 等价地,函数是函数名或lambda表达式的函数应用程序

以上两点是否回答了我在上一个问题?

您也会问(在链接条目上)“mult(3)不是一个部分应用程序,所以它有意义吗?”

我想我已经回答了你之前的一个问题

否,
mult
的类型是
(Int,Int)->Int
,即其参数必须具有类型
(Int,Int)
。但是
3
不能有那种类型;它的类型只是
Int
。要计算mult 3的结果,请定义

mult :: (Int, Int) -> Int
mult (x, y) = x * y
参考,计算过程如下:

mult 3
= case 3 of (x, y) -> x * y
***error: pattern match failure
事实上,如果Haskell是一种非类型化语言,就会出现这种情况。由于它有类型,编译期间检测到
3
(Int,Int)
的类型不匹配,程序被拒绝。(*)



(*)
3::Num a=>a
,即它的类型可以是
Int
Float
,等等,但肯定不能是元组。。。嗯,如果没有为元组定义
Num
实例,它就不能,但是假设没有。这也意味着,在发现没有为任何导入模块中的任何元组类型定义Num实例后,程序实际上将在运行时被拒绝。。。但是让我们把它留作一个脚注。

什么算是redex通常取决于语言。表达式的语法以各种结构的引入和消除形式成对出现;redex是当一种特定类型的构造的引入形式和消除形式被适当地并置时

对于函数,lambda是介绍(它们是创建函数的标准方法,而以前没有),而应用程序是消除(它们是使用函数的标准方法)。因此,函数redex是lambda对某物的应用,例如
(\x->e1)e2
形式的某物。(仅此而已!将变量应用于某个对象并不是函数redex。通常我会假设这是隐含的,但您的问题明确询问了这一点,所以…)

对于声明,
-绑定或类似的方法是介绍(它们是声明名称具有给定值的规范方法),变量是消除(它们是使用声明值的规范方法)。因此,声明redex是
let
绑定范围内的一个术语,它引用
let
绑定变量,例如,e2中
let x=e1形式的某种东西,其中
e2
提到
x

对于代数数据类型,类型的数据构造函数是介绍(它们是在类型中创建值的规范方式),
case
表达式是消除(它们是使用代数类型值的规范方式)。因此代数数据类型redex是一个
案例
,其scrutinee是一个完全饱和的构造函数应用程序,例如
案例构造函数arg1 arg2 arg3。。。pat1->e1;pat2->e2


这些只是一些配对的例子。并非所有语言都有这三种结构;还有一些语言具有额外的构造(例如可变引用、异常等,每种语言都有自己的引入和消除形式)。但我认为这应该让你对“redex”的含义有所了解:它是一种结构,在这种结构中,可以进行一些计算,从而在计算表达式的值方面取得进展。

是的。在某些情况下,当
e
的计算结果为“足够”时,我也会将
case e of…
称为redex,这样它就暴露了足够多的构造函数,导致整个表达式减少,删除了
case
。你的意思是Haskell不允许部分应用吗?什么?如果
mult(x,y)=x*y
,则
mult 3
类型错误。它没有意义;被类型系统拒绝。如果
prod x y=x*y
,那么
prod::Int->Int->Int
,对于
x::Int
prod x::Int->Int
类型正确,有意义,是允许的。部分应用程序是在Haskell中定义的吗?这在其他语言中非常复杂,会让您感到困惑,让你期待Haskell这里也会发生一些复杂的事情。但在Haskell中,它实际上非常简单。你只需要停止用“实现”来思考,转而用“定义”来思考
fxy=…
fx=(\y->…)
只是写同一件事的两种不同方式。@Tim因为这三个值必须具有相同的类型。在割圆数上加一个复数,或在有理数上加一个多项式是没有意义的。但是,添加两个不同的值,这两个值都是有理的,这是非常有意义的(添加的结果也是有理的)。谢谢。你列出了三种redex,我想它们不是这样的。在某些理论中,redex是一个概念吗?在lambda演算中?@Tim是的,redex是lambda演算中的一个概念。lambda演算是否只涵盖一种redex:函数redex?@Tim有基于lambda演算的语言,具有我在回答中提到的每种功能以及更多功能。人们谈论“lambda演算”,但事实并非如此——这个主题有很多变化。我的意思是“lambda演算”。基于lambda演算的语言也可以是bas