Function 在Haskell中,(+;)是一个函数,(+;)2)是一个函数,(+;)2)是5。到底是怎么回事?

Function 在Haskell中,(+;)是一个函数,(+;)2)是一个函数,(+;)2)是5。到底是怎么回事?,function,haskell,functional-programming,programming-languages,partial-application,Function,Haskell,Functional Programming,Programming Languages,Partial Application,这怎么可能,那里发生了什么 这个有名字吗 其他哪些语言有同样的行为 如果没有强大的打字系统,会有吗 在Haskell中,您可以获取两个参数的函数,将其应用于一个参数,然后获取一个参数的函数。事实上,严格来说,+不是两个参数的函数,它是一个参数的函数,返回一个参数的函数 用外行的话说,+是实际的函数,它正在等待接收一定数量的参数(在本例中为2个或更多),直到返回。如果不给它两个或多个参数,那么它将仍然是一个等待另一个参数的函数 它叫 许多函数语言(Scala、Scheme等) 大多数函数式语言都是

这怎么可能,那里发生了什么

  • 这个有名字吗

  • 其他哪些语言有同样的行为

  • 如果没有强大的打字系统,会有吗


  • 在Haskell中,您可以获取两个参数的函数,将其应用于一个参数,然后获取一个参数的函数。事实上,严格来说,+不是两个参数的函数,它是一个参数的函数,返回一个参数的函数

  • 用外行的话说,
    +
    是实际的函数,它正在等待接收一定数量的参数(在本例中为2个或更多),直到返回。如果不给它两个或多个参数,那么它将仍然是一个等待另一个参数的函数
  • 它叫
  • 许多函数语言(Scala、Scheme等)
  • 大多数函数式语言都是强类型的,但这最终还是很好的,因为它减少了错误,这在企业或关键系统中非常有效

  • 作为旁注,Haskell语言是以Haskell Curry命名的,他在研究组合逻辑时重新发现了函数式Curry现象。

    如果你看一下类型,这种行为非常简单直观。为了避免像
    +
    这样的中缀运算符的复杂性,我将使用函数
    plus
    。我还将专门研究
    plus
    ,只处理
    Int
    ,以减少typeclass行噪声

    假设我们有一个类型为
    Int->Int->Int
    的函数
    plus
    。一种读取方法是“两个
    Int
    s的函数返回
    Int
    ”。但是这种符号对于阅读来说有点笨拙,不是吗?返回类型在任何地方都没有特别指出。为什么我们要这样写函数类型签名?因为
    ->
    是右关联的,所以等价的类型应该是
    Int->(Int->Int)
    。这看起来更像是在说“从
    Int
    到(从
    Int
    Int
    的函数)”。但这两种类型实际上完全相同,后一种解释是理解这种行为如何运作的关键

    Haskell将所有函数视为从单个参数到单个结果的函数。您可能会想到一些计算,其中计算结果取决于两个或多个输入(例如
    加上
    )。Haskell说,函数
    plus
    是一个接受单个输入的函数,并生成另一个函数的输出。第二个函数接受单个输入并生成一个数字输出。因为第二个函数是由第一个函数计算的(并且对于第一个函数的不同输入将是不同的),所以“最终”输出可以依赖于两个输入,因此我们可以使用这些函数实现多个输入的计算,这些函数只取单个输入

    我保证如果你看一下这些类型,这会很容易理解。下面是一些带有显式注释类型的示例表达式:

    plus       :: Int -> Int -> Int
    plus 2     ::        Int -> Int
    plus 2 3   ::               Int
    
    如果某个东西是一个函数,并将其应用于一个参数,那么要获得该应用程序结果的类型,只需从函数的类型中删除第一个箭头之前的所有内容。如果这留下了一个有更多箭头的类型,那么您仍然有一个函数!在表达式右侧添加参数时,将从其类型左侧删除参数类型。该类型立即明确了所有中间结果的类型,以及为什么
    plus 2
    是一个可以进一步应用的函数(其类型有一个箭头),而
    plus 2 3
    不是(其类型没有箭头)

    “curry”是将两个参数的函数转换为一个参数的函数的过程,该函数返回另一个参数的函数,该函数返回原始函数返回的任何内容。它还用来指像Haskell这样的语言的属性,这些语言自动地让所有函数以这种方式工作;人们会说Haskell“是一种咖喱语”或“有咖喱语”,或“有咖喱语的功能”

    请注意,这项工作尤其优雅,因为Haskell的函数应用程序语法是简单的标记邻接。您可以自由阅读
    plus 2 3
    ,将
    plus
    应用于2个参数,或将
    plus
    应用于
    2
    ,然后将结果应用于
    3
    ;你可以用最适合你当时所做的任何一种方式对它进行心理建模


    在使用带括号参数列表的类C函数应用程序的语言中,这种情况有点不正常
    plus(2,3)
    plus(2)(3)
    非常不同,在使用这种语法的语言中,所涉及的
    plus
    的两个版本可能具有不同的类型。因此,具有这种语法的语言往往不会一直对所有函数进行咖喱,甚至不会对任何您喜欢的函数进行自动咖喱。但是这种语言在历史上也不倾向于将函数作为第一类值,这使得缺少currying成为一个没有意义的问题。

    在Haskell中,所有函数只接受一个输入,只产生一个输出。有时,一个函数的输入或输出可以是另一个函数。函数的输入或输出也可以是元组。您可以通过以下两种方式之一模拟具有多个输入的函数:

    • 使用元组作为输入
      (in1,in2)->out

    • 使用函数作为输出*
      in1->(in2->out)

    同样,您可以通过以下两种方式之一模拟具有多个输出的函数:

    • 使用元组作为输出*
      in->(out1,out2)

    • 将函数用作“第二输入”(a