我对可简化表达式(即 redex)的理解是否正确?
Is my understanding of a reducible expression i.e. redex correct?
Hutton 在 Haskell 中的编程说:
An expression that has the form of a function applied to one or more arguments that can be ‘reduced’ by performing the application is called a reducible expression, or redex for short.
是一个可简化的表达式,即 redex 正好
一个函数应用程序,其中函数不是另一个函数应用程序的结果,
等价于函数应用程序,其中函数是函数名或 lambda 表达式?
以上两点是否是我之前在的问题的答案?
您还询问(链接条目上的)"Isn't mult(3) a partial application, so it makes sense?"
我想我已经回答了这个问题 你之前的一个问题。
不,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,编译时检测到type mismatch of 3
and (Int, Int)
,程序被reject . (*)
(*) 3 :: Num a => a
,即它的类型可以是Int
,Float
等,但肯定不能是元组.. . 好吧,如果没有为元组定义的 Num
实例,它不能,但假设没有。这也意味着该程序实际上将在 运行 时间被拒绝,因为它发现没有 Num 个实例被定义为任何元组类型导入的模块...但让我们将其作为脚注。
什么算作 redex 通常取决于语言。表达式的句法以各种结构的引入和消除形式成对出现; redex 是指特定类型的构造的引入和消除形式适当并置。
对于函数,lambda 是介绍(它们是在之前没有函数时创建函数的规范方式),而应用程序是消除(它们是使用函数的规范方式)。因此,函数 redex 是将 lambda 应用于某些事物,例如(\x -> e1) e2
形式的东西。 (而且只有这个!变量对某物的应用 不是 函数 redex。通常我会假设这是隐含的,但你的问题明确询问这个,所以......)
对于声明,let
-绑定或类似的是引入(它们是声明名称具有给定值的规范方式)并且变量是消除(它们是使用声明值的规范方式).因此,声明 redex 是 let
绑定范围内的一个术语,它引用了 let
绑定变量,例如let x = e1 in e2
形式的东西 e2
提到 x
.
对于代数数据类型,类型的数据构造函数是引入(它们是在类型中创建值的规范方式),case
表达式是消除(它们是使用值的规范方式)代数类型)。因此,代数数据类型 redex 是一个 case
,其审查者是一个 fully-saturated 构造函数应用程序,例如case Constructor arg1 arg2 arg3 ... of pat1 -> e1; pat2 -> e2; ...
.
这些只是配对的一些例子。并非所有语言都具有这三种结构。并且有些语言具有额外的构造(例如可变引用、异常等,每种都有自己的引入和消除形式)。但我认为这应该让您了解 "redex" 的含义:它是一种可以进行一些计算以在计算表达式值方面取得进展的结构。
Hutton 在 Haskell 中的编程说:
An expression that has the form of a function applied to one or more arguments that can be ‘reduced’ by performing the application is called a reducible expression, or redex for short.
是一个可简化的表达式,即 redex 正好
一个函数应用程序,其中函数不是另一个函数应用程序的结果,
等价于函数应用程序,其中函数是函数名或 lambda 表达式?
以上两点是否是我之前在
您还询问(链接条目上的
我想我已经回答了这个问题
不,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,编译时检测到type mismatch of 3
and (Int, Int)
,程序被reject . (*)
(*) 3 :: Num a => a
,即它的类型可以是Int
,Float
等,但肯定不能是元组.. . 好吧,如果没有为元组定义的 Num
实例,它不能,但假设没有。这也意味着该程序实际上将在 运行 时间被拒绝,因为它发现没有 Num 个实例被定义为任何元组类型导入的模块...但让我们将其作为脚注。
什么算作 redex 通常取决于语言。表达式的句法以各种结构的引入和消除形式成对出现; redex 是指特定类型的构造的引入和消除形式适当并置。
对于函数,lambda 是介绍(它们是在之前没有函数时创建函数的规范方式),而应用程序是消除(它们是使用函数的规范方式)。因此,函数 redex 是将 lambda 应用于某些事物,例如(\x -> e1) e2
形式的东西。 (而且只有这个!变量对某物的应用 不是 函数 redex。通常我会假设这是隐含的,但你的问题明确询问这个,所以......)
对于声明,let
-绑定或类似的是引入(它们是声明名称具有给定值的规范方式)并且变量是消除(它们是使用声明值的规范方式).因此,声明 redex 是 let
绑定范围内的一个术语,它引用了 let
绑定变量,例如let x = e1 in e2
形式的东西 e2
提到 x
.
对于代数数据类型,类型的数据构造函数是引入(它们是在类型中创建值的规范方式),case
表达式是消除(它们是使用值的规范方式)代数类型)。因此,代数数据类型 redex 是一个 case
,其审查者是一个 fully-saturated 构造函数应用程序,例如case Constructor arg1 arg2 arg3 ... of pat1 -> e1; pat2 -> e2; ...
.
这些只是配对的一些例子。并非所有语言都具有这三种结构。并且有些语言具有额外的构造(例如可变引用、异常等,每种都有自己的引入和消除形式)。但我认为这应该让您了解 "redex" 的含义:它是一种可以进行一些计算以在计算表达式值方面取得进展的结构。