最外部的评估策略如何评估功能的部分应用和咖喱函数的应用

时间:2019-07-14 01:14:37

标签: haskell functional-programming evaluation currying partial-application

赫顿说

在Haskell编程

  

在计算表达式时,应以什么顺序执行归约?一种常见   称为最内在评估的策略是,始终选择最内在的Redex,   不含其他redex。如果最里面的redex不止一个,按照惯例,我们选择一个   从表达式最左边的位置开始。

     

对表达式进行评估的另一种常见策略是对最内层的评估,始终是   选择一个最外部的Redex,因为它不包含在其他Redex中。如果超过   然后像以前一样选择一个这样的redex,它从最左边的位置开始。这并不奇怪,   这种评估策略称为最外部评估

在函数的部分应用中,例如mult(3)(4),其中mult被定义为

mult    ::  (Int,Int)   ->  Int
mult    (x,y)   =   x   *   y

最里面的评估将首先将mult(3)评估为\y->3*y,然后评估(\y->3*y)4。 最外部的评估如何评估mult(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)

1 个答案:

答案 0 :(得分:6)

唯一明智的解释方式:

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的应用程序虽然是最外层的 application ,但它不是redex。它无法减少,因为要应用的((\x -> \y -> x * y) 3)不是lambda表达式。 (这是lambda表达式对参数的应用。)

因此,与首次出现相反,第(1)行中只有一个redex,并且最内部和最外部的还原策略选择相同的redex。