Function 部分应用函数

Function 部分应用函数,function,haskell,partially-applied-type,Function,Haskell,Partially Applied Type,在研究函数式编程时,经常会出现部分应用函数的概念。在Haskell中,内置函数take被认为是部分应用的 我仍然不清楚部分应用函数的确切含义,或者它的使用/含义。函数本身不能“部分应用”或不“部分应用”。这是一个毫无意义的概念 当你说一个函数是“部分应用的”时,你指的是如何调用该函数(也称为“应用的”)。如果调用该函数及其所有参数,则称其为“完全应用”。如果缺少某些参数,则该函数称为“部分应用” 例如: -- The function `take` is fully applied here:

在研究函数式编程时,经常会出现部分应用函数的概念。在Haskell中,内置函数
take
被认为是部分应用的


我仍然不清楚部分应用函数的确切含义,或者它的使用/含义。

函数本身不能“部分应用”或不“部分应用”。这是一个毫无意义的概念

当你说一个函数是“部分应用的”时,你指的是如何调用该函数(也称为“应用的”)。如果调用该函数及其所有参数,则称其为“完全应用”。如果缺少某些参数,则该函数称为“部分应用”

例如:

-- The function `take` is fully applied here:
oneTwoThree = take 3 [1,2,3,4,5]

-- The function `take` is partially applied here:
take10 = take 10   -- see? it's missing one last argument

-- The function `take10` is fully applied here:
oneToTen = take10 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,42]
部分函数应用程序的结果是另一个函数-仍然“期望”获取其缺少的参数的函数-如上例中的
take10
,仍然“期望”接收列表


当然,一旦你进入高阶函数,它会变得更复杂一些,也就是说,函数以其他函数作为参数,或者返回其他函数作为结果。考虑这个函数:

mkTake n = take (n+5)
(+ 5) :: Num a => a -> a
add = \x -> x + 3
函数
mkTake
只有一个参数,但它返回另一个函数作为结果。现在,考虑一下:

x = mkTake 10
y = mkTake 10 [1,2,3]
在第一行,函数
mkTake
显然是“完全应用的”,因为它有一个参数,这正是它所期望的参数数量。但是第二行也是有效的:因为
mkTake 10
返回一个函数,所以我可以用另一个参数调用这个函数。那么,它使
mkTake
成为什么呢?“过度应用”,我猜

然后考虑一个事实:(除非编译器优化)所有的函数在数学上都是一个参数的函数。这怎么可能?当您声明一个函数时,

take nl=…
,您“概念上”说的是
take=\n->\l->…
——也就是说,
take
是一个函数,它接受参数
n
,并返回另一个接受参数
l
并返回一些结果的函数


因此,底线是“部分应用程序”的概念实际上并没有严格定义,它只是一个方便的缩写,用来指那些“应该”(如常识所示)接受N个参数,但被赋予M函数本身不能“部分应用”或不“部分应用”。这是一个毫无意义的概念

当你说一个函数是“部分应用的”时,你指的是如何调用该函数(也称为“应用的”)。如果调用该函数及其所有参数,则称其为“完全应用”。如果缺少某些参数,则该函数称为“部分应用”

例如:

-- The function `take` is fully applied here:
oneTwoThree = take 3 [1,2,3,4,5]

-- The function `take` is partially applied here:
take10 = take 10   -- see? it's missing one last argument

-- The function `take10` is fully applied here:
oneToTen = take10 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,42]
部分函数应用程序的结果是另一个函数-仍然“期望”获取其缺少的参数的函数-如上例中的
take10
,仍然“期望”接收列表


当然,一旦你进入高阶函数,它会变得更复杂一些,也就是说,函数以其他函数作为参数,或者返回其他函数作为结果。考虑这个函数:

mkTake n = take (n+5)
(+ 5) :: Num a => a -> a
add = \x -> x + 3
函数
mkTake
只有一个参数,但它返回另一个函数作为结果。现在,考虑一下:

x = mkTake 10
y = mkTake 10 [1,2,3]
在第一行,函数
mkTake
显然是“完全应用的”,因为它有一个参数,这正是它所期望的参数数量。但是第二行也是有效的:因为
mkTake 10
返回一个函数,所以我可以用另一个参数调用这个函数。那么,它使
mkTake
成为什么呢?“过度应用”,我猜

然后考虑一个事实:(除非编译器优化)所有的函数在数学上都是一个参数的函数。这怎么可能?当您声明一个函数时,

take nl=…
,您“概念上”说的是
take=\n->\l->…
——也就是说,
take
是一个函数,它接受参数
n
,并返回另一个接受参数
l
并返回一些结果的函数

因此,底线是“部分应用程序”的概念实际上并没有严格定义,它只是一个方便的缩写,用来指那些“应该”(如常识所示)接受N个参数,但被赋予M经典的例子是

add     :: Int -> Int -> Int
add x y = x + y
add
函数接受两个参数并将它们相加,现在我们可以实现了

increment = add 1
通过部分应用
add
,它现在等待另一个参数。

经典示例是

add     :: Int -> Int -> Int
add x y = x + y
add
函数接受两个参数并将它们相加,现在我们可以实现了

increment = add 1

通过部分应用
add
,它现在等待另一个参数。

通过示例可以最好地理解这一点。下面是加法运算符的类型:

(+) :: Num a => a -> a -> a
这是什么意思?如你所知,它需要两个数字并输出另一个。正当嗯,有点

你看,
a->a->a实际上意味着:
a->(a->a)
。哇,看起来怪怪的!这意味着
(+)
是一个接受一个参数并输出一个函数(!!)的函数,该函数也接受一个参数并输出一个值

这意味着您可以将一个值提供给
(+)
,以获得另一个部分应用的函数:

mkTake n = take (n+5)
(+ 5) :: Num a => a -> a
add = \x -> x + 3
此函数接受一个参数并向其添加五个参数。现在,用一些参数调用新函数:

Prelude> (+5) 3
8
给你!部分功能应用在工作中

注意
(+5)3的类型:

(+5) 3 :: Num a => a
看看我们最终得到了什么:

  • (+)::Num a=>a->a->a
  • (+5)::Num a=>a->a
  • (+5)3::Num a=>a
  • 您是否看到类型签名中的
    a
    s的数量在每次添加时都会减少一个