首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Haskell中,(+)是函数,((+) 2)是函数,((+) 2)是5,到底发生了什么?

在Haskell中,(+)是函数,((+) 2)是函数,((+) 2)是5,到底发生了什么?
EN

Stack Overflow用户
提问于 2012-06-27 00:42:55
回答 5查看 3.4K关注 0票数 12
  1. 这怎么可能,怎么回事?
  2. 这个有名字吗?
  3. 其他语言有同样的行为吗?
  4. 没有强大的打字系统吗?
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-06-27 01:20:07

如果你看看这些类型,这种行为是非常简单和直观的。为了避免像+这样的infix操作符的复杂性,我将使用函数plus。我还将专门研究plus,只在Int上工作,以减少典型的线路噪声。

假设我们有一个函数plus,类型为Int -> Int -> Int。一种读取方法是“两个Ints的函数,返回一个Int”。但是这个符号读起来有点笨拙,不是吗?返回类型在任何地方都不是专门挑出来的。为什么我们要这样写函数类型签名呢?因为->是正确的关联类型,所以等效的类型将是Int -> (Int -> Int)。这看起来更像是“从Int到(从IntInt的函数)的函数”。但这两种类型实际上是完全相同的,后一种解释是理解这种行为如何运作的关键。

Haskell认为所有函数都是从一个参数到一个结果。在计算结果取决于两个或多个输入(如plus)的情况下,您可能想到了一些计算。Haskell说,函数plus是一个接受单个输入并生成输出的函数,它是另一个函数。第二个函数接受一个输入并产生一个输出,这是一个数字。由于第二个函数是由第一个(对于第一个函数的不同输入将不同)计算的,所以“最终”输出可以依赖于两个输入,因此我们可以使用这些只需要一个输入的函数来实现多个输入的计算。

我承诺过,如果您查看类型,这将非常容易理解。下面是一些带有显式注释类型的示例表达式:

代码语言:javascript
复制
plus       :: Int -> Int -> Int
plus 2     ::        Int -> Int
plus 2 3   ::               Int

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

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

请注意,由于Haskell用于函数应用程序的语法是简单的令牌邻接,所以这一工作特别出色。您可以自由地将plus 2 3理解为对2个参数的plus应用程序,或者将plus应用于2,然后将结果应用于3;您可以从心理上对其建模,不管您当时正在做什么。

在C类函数应用程序的圆括号参数列表的语言中,这会被分解一些。plus(2, 3)plus(2)(3)非常不同,在具有这种语法的语言中,涉及到的两个plus版本可能有不同的类型。因此,具有这种语法的语言往往不会一直对所有函数进行匆忙处理,甚至不会自动对任何您喜欢的函数进行竞逐。但是,这些语言在历史上也往往不具有作为头等值的函数,这使得缺乏竞逐成为一个毫无意义的问题。

票数 42
EN

Stack Overflow用户

发布于 2012-06-27 04:47:42

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

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

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

  • 使用元组作为输出* in -> (out1, out2)
  • 使用一个函数作为“第二个输入”(作为输出的la函数) in -> ((out1 -> (out2 -> a)) -> a)

*这种方式通常受到Haskellers的青睐。

(+)函数以典型的Haskell方式模拟两个输入作为输出。(专门用于Int以便于通信:)

(+) :: Int -> (Int -> Int)

为了方便起见,->是正确关联的,因此也可以编写(+)的类型签名。

(+) :: Int -> Int -> Int

(+)是一个接收数字的函数,它生成另一个从数字到数字的函数。

(+) 5是将(+)应用于参数5的结果,因此,它是一个从数字到数字的函数。

(5 +)是另一种编写(+) 5的方法

2 + 3是编写(+) 2 3的另一种方式。函数应用程序是左关联的,因此这是编写(((+) 2) 3)的另一种方式。换句话说:将函数(+)应用于输入2。结果将是一个函数。接受该函数,并将其应用于输入3。其结果是一个数字。

因此,(+)是一个函数,(5 +)是一个函数,(+) 2 3是一个数字。

票数 9
EN

Stack Overflow用户

发布于 2012-06-27 00:45:59

在Haskell中,您可以使用两个参数的函数,将其应用于一个参数,并得到一个参数的函数。事实上,严格地说,+不是两个参数的函数,而是一个返回一个参数函数的函数。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11217874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档