瑞典人怎么会非常瑞典问候?

Dav*_*ang 7 haskell composition higher-order-functions

考虑以下Haskell定义,取自YouTube上优秀的Haskell视频:

import Data.List
greeting = "Hello"
swedish = intersperse 'f'
very f x = f (f (f x))
Run Code Online (Sandbox Code Playgroud)

如果我们将它们加载到GHCi中,我们会看到以下结果:

ghci> swedish greeting
"Hfeflflfo"
ghci> very swedish greeting
"Hfffffffeffffffflffffffflfffffffo"
ghci> very very swedish greeting
"Hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffff... (536,870,913 chars total)
Run Code Online (Sandbox Code Playgroud)

前两个输出我完全理解.A swedish greeting出现穿插fs,a very swedish greeting只是a swedish (swedish (swedish greeting)),穿出三次.

但究竟在第三个输入线上发生了什么?我对Haskell语法的理解(相当不完整)表明,以空格分隔的表达式序列被解释为函数调用,其中第一个表达式是函数,其余表达式是参数.在这种情况下,如何在最外层very被称为三个参数(very,swedish,和greeting)时,它只能定义为接受两个?

如果它有帮助,似乎a very very swedish greeting等同于a swedish $ swedish $ swedish $ swedish $ ... (27 layers of swedish) ... $ swedish $ swedish greeting.

Dan*_*att 11

你说:

我对Haskell语法的理解(相当不完整)表明,以空格分隔的表达式序列被解释为函数调用,其中第一个表达式是函数,其余表达式是参数.

你是对的,这不完全理解实际发生的事情.从你的例子:

very very swedish greeting
Run Code Online (Sandbox Code Playgroud)

这与:

((very very) swedish) greeting
Run Code Online (Sandbox Code Playgroud)

这是因为函数应用程序是左关联的.此外,Haskell中的每个函数都接受一个输入并返回一个结果.您认为接受多个输入的函数实际上是接受单个输入并返回函数作为结果的函数.

这也解释了为什么箭头( - >)分隔函数输入导致函数类型.考虑以下类型++:

(++) :: [a] -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

这与:

(++) :: [a] -> ([a] -> [a])
Run Code Online (Sandbox Code Playgroud)

您可以将++运算符视为取两个列表并返回一个列表,但实际上它是一个输入(列表)的函数,它返回一个返回列表的输入(另一个列表)的函数.

总而言之,你可以希望看到它very very本身就是一个有效的表达式(并且碰巧具有相同的类型very).

very very x
Run Code Online (Sandbox Code Playgroud)

相当于:

very (very (very x))
Run Code Online (Sandbox Code Playgroud)