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

时间:2019-07-14 11:48:08

标签: haskell functional-programming redex

Hutton在Haskell中进行编程说:

  

将具有函数形式的表达式应用于一个或多个参数,可以通过执行该应用程序对其进行“约简”,称为可约简表达式,或简称为redex。

是可还原的表达式,即完全redex

  • 一个功能应用程序,其中该功能不是另一个功能应用程序的结果

  • 等同于一个函数应用程序,其中函数是函数名还是lambda表达式?

以上两点之一是我在How does the outermost evaluation strategy evaluate partial application of a function and application of a curried function上一个问题的答案吗?

2 个答案:

答案 0 :(得分:2)

什么才算是redex取决于语言。表达式的语法是成对出现和消除各种结构形式的对。 redex是将特定类型的构造的引入和消除形式适当地并置的情况。

对于函数,lambdas是简介(它们是以前没有函数时创建函数的规范方法),而应用程序是消除(它们是使用函数的规范方法)。因此,函数redex是将lambda应用到某些东西,例如格式为(\x -> e1) e2。 (而且仅此!将变量应用于某物不是 函数redex。通常我认为这是隐含的,但是您的问题明确询问了这个内容,所以...)

对于声明,let绑定或类似内容是引言(它们是声明名称具有给定值的规范方法),变量是消除符(它们是使用声明值的规范方法)。因此,声明redex是let绑定范围内的一个术语,它引用一个let绑定的变量,例如格式为let x = e1 in e2,其中e2提到x

对于代数数据类型,类型的数据构造函数是引言(它们是在类型中创建值的规范方法),而case表达式是消除(它们是使用代数类型的值的规范方法) )。因此,代数数据类型redex是case,其检查对象是完全饱和的构造函数应用程序,例如case Constructor arg1 arg2 arg3 ... of pat1 -> e1; pat2 -> e2; ...

这些只是配对的一些示例。并非所有语言都具有这三种构造;还有一些带有其他构造的语言(例如,可变引用,异常等,每种都有自己的介绍和排除形式)。但是我认为这应该使您了解“ redex”的含义:在这种结构中,可以进行一些计算以逐步找出表达式的值。

答案 1 :(得分:1)

您还问(链接条目上的{in the comments“不是对(3)进行部分申请,所以有意义吗?”

我想我已经in my answer回答了您以前的一个问题。

否,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是非类型化语言,情况就是这样。由于具有 types ,因此在编译过程中检测到3(Int, Int)类型不匹配,并且该程序被拒绝。 (*)


(*)3 :: Num a => a,即它的类型可以是IntFloat等,但是肯定不能是元组...好吧,如果没有不能为元组定义一个Num实例,但是可以说没有一个实例。这也意味着在发现在任何导入模块中没有为任何元组类型定义 Num 实例之后,该程序实际上将在 run 时被拒绝...但是让我们离开作为脚注。