Haskell 最外层的评估策略如何评估函数的部分应用和当前函数的应用
Hutton用Haskell编程说 计算表达式时,应按什么顺序执行缩减?一个普通的 被称为“最内层评估”的策略是始终选择最内层的redex,即 不包含其他redex。如果有多个最里面的redex,按照惯例,我们会选择 从表达式中最左侧的位置开始 对表达式求值的另一种常用策略是,始终使用 选择最外层的redex,因为它不包含在其他redex中。如果超过 一个这样的redex,然后像前面一样,我们选择从最左边开始的。毫不奇怪, 此评估策略称为最外层评估 在函数的部分应用中,例如,Haskell 最外层的评估策略如何评估函数的部分应用和当前函数的应用,haskell,functional-programming,evaluation,currying,partial-application,Haskell,Functional Programming,Evaluation,Currying,Partial Application,Hutton用Haskell编程说 计算表达式时,应按什么顺序执行缩减?一个普通的 被称为“最内层评估”的策略是始终选择最内层的redex,即 不包含其他redex。如果有多个最里面的redex,按照惯例,我们会选择 从表达式中最左侧的位置开始 对表达式求值的另一种常用策略是,始终使用 选择最外层的redex,因为它不包含在其他redex中。如果超过 一个这样的redex,然后像前面一样,我们选择从最左边开始的。毫不奇怪, 此评估策略称为最外层评估 在函数的部分应用中,例如,mult(3)(4)
mult(3)(4)
,其中mult
定义为
mult :: (Int,Int) -> Int
mult (x,y) = x * y
最内层的求值将首先以\y->3*y
的形式求值mult(3)
,然后求值(\y->3*y)4
。
最外层的评估将如何评估多(3)(4)
在应用当前函数时,例如,mult'(3)(4)
,其中
mult' :: Int -> Int -> Int
mult' x = \y -> x * y
最里面的求值将首先求值mult'(3)
为\y->3*y
,然后求值(\y->3*y)4
。
最外层的评估将如何评估
mult'(3)(4)
?唯一合理的解释方式:
mult :: (Int, Int) -> Int
mult (x,y) = x * y
在你的大问题的上下文中,是作为一个一元函数,它接受一个元组类型的参数(Int,Int)
。因此,mult
不能部分应用。特别是,mult(3)
没有任何意义,因为3
不是(Int,Int)
类型的元组
因此,表达式mult(3,4)
在Hutton所指的意义上的缩减是相同的,无论您使用最外层还是最内层的缩减。这里只有一个redex/应用程序,将mult
应用到(3,4)
,最外层和最内层的还原都会得到还原:
mult (3,4)
=> 3 * 4
=> 12
对于功能:
mult' :: Int -> Int -> Int
mult' x y = x * y
或相当于:
mult' = \x -> (\y -> x * y)
表达式mult'3 4
或等效的(mult'3)4
进行最内部的缩减,如下所示:
(mult' 3) 4
= ((\x -> (\y -> x * y)) 3) 4
=> (\y -> 3 * y) 4
=> 3 * 4
=> 12
奇怪的是,最外层的还原以完全相同的方式进行:
(mult' 3) 4
= ((\x -> (\y -> x * y)) 3) 4 -- (1)
=> (\y -> 3 * y) 4
=> 3 * 4
=> 12
这是因为第(1)行中的((\x->\y->x*y)3
到4
的应用程序,而它是最外层的应用程序,而不是redex。它不能减少,因为应用的对象不是lambda表达式。(这是lambda表达式对参数的应用。)
因此,与第一次出现相反,第(1)行中只有一个redex,最内层和最外层的还原策略选择相同的redex。唯一合理的解释方式是:
mult :: (Int, Int) -> Int
mult (x,y) = x * y
在你的大问题的上下文中,是作为一个一元函数,它接受一个元组类型的参数(Int,Int)
。因此,mult
不能部分应用。特别是,mult(3)
没有任何意义,因为3
不是(Int,Int)
类型的元组
因此,表达式mult(3,4)
在Hutton所指的意义上的缩减是相同的,无论您使用最外层还是最内层的缩减。这里只有一个redex/应用程序,将mult
应用到(3,4)
,最外层和最内层的还原都会得到还原:
mult (3,4)
=> 3 * 4
=> 12
对于功能:
mult' :: Int -> Int -> Int
mult' x y = x * y
或相当于:
mult' = \x -> (\y -> x * y)
表达式mult'3 4
或等效的(mult'3)4
进行最内部的缩减,如下所示:
(mult' 3) 4
= ((\x -> (\y -> x * y)) 3) 4
=> (\y -> 3 * y) 4
=> 3 * 4
=> 12
奇怪的是,最外层的还原以完全相同的方式进行:
(mult' 3) 4
= ((\x -> (\y -> x * y)) 3) 4 -- (1)
=> (\y -> 3 * y) 4
=> 3 * 4
=> 12
这是因为第(1)行中的((\x->\y->x*y)3
到4
的应用程序,而它是最外层的应用程序,而不是redex。它不能减少,因为应用的对象不是lambda表达式。(这是lambda表达式对参数的应用。)
因此,与第一次出现相反,第(1)行中只有一个redex,而最内层和最外层的还原策略选择相同的redex。最内层和最外层的评估都同意您的条件,因为它们非常简单,它们只有一个redex。但是,请考虑<代码> Mult(Mult 3 4)5 < /Cord>,现在必须在减少<代码> Mult 3 4 < /C>第一或减少<代码> Mult(…)5 < /代码>之间进行选择。函数应用程序是否为可归约表达式,即redex,当且仅当函数应用程序不是另一个函数应用程序的结果,即当且仅当函数应用程序必须是函数名或lambda表达式时,最内层和最外层的计算同意您的条款,因为它们非常简单,所以它们只有一个redex。但是,请考虑<代码> Mult(Mult 3 4)5 < /Cord>,现在必须在减少<代码> Mult 3 4 < /C>第一或减少<代码> Mult(…)5 < /代码>之间进行选择。函数应用程序是否为可还原表达式,即redex,当且仅当函数应用程序不是另一个函数应用程序的结果,即当且仅当函数应用程序必须是函数名或lambda表达式谢谢。函数应用程序是否为可约表达式,即redex,当且仅当函数应用程序不是另一个函数应用程序的结果,即当且仅当