h1 f g x y = f (g x y) x
因此,从左到右获取参数列表:
f是一个应用于两个参数的函数:第一个是结果,(g x y)第二个是x
- 我们还不知道第一个参数是什么类型,所以我们称之为
a
- 我们也不知道第二种类型,所以我们称之为
b
- 我们也不知道结果类型(所以我们称之为
c),但我们知道这一定是返回的类型h1
g是应用于两个参数的函数:第一个是x,第二个y
- 我们知道 的第一个参数
g与 的第二个参数相同f,所以它必须是相同的类型:我们已经标记了b
gis的第二个参数y,我们还没有分配占位符类型,所以它会依次获得下一个,d
g的结果是 的第一个参数f,我们已经将其标记为a
- 第三个参数是
x,因为这是 的第二个参数f,我们已经标记了它的类型b
- 第四个参数是
y,这是 的第二个参数g,所以我们已经标记了它的类型d
- 的结果
h1是应用f到的结果(g x y) x,正如我们之前所说,所以它具有相同的类型,已经标记c
尽管我们按顺序处理了参数列表,但为每个参数标记、推断和统一类型的实际过程是通过查看.h1
因此,我的第一个项目符号可以详细说明为:
f是要考虑的第一个参数,所以让我们看看h1(之后的所有内容=)的主体,看看它是如何使用的
f (g x y) x表示f应用于(g x y) x,因此f必须是函数
(g x y)在括号中,这意味着正在评估这些括号内的任何内容,并且该评估的结果是f
x只是一个简单的参数f,直接从h1自己的参数列表传递
- 所以,
f是一个有两个参数的函数
如果它有助于阅读f (g x y) x,您可以考虑使用类 C 表示法的等效表达式是f(g(x,y), x). 在这里,您可以立即看到f和g是带有两个参数的函数,f第一个参数是g返回的值,等等。
请注意,表达式的左侧h1 f g x y仅给出了一条类型信息:它h1是一个有四个参数的函数。参数名称本身只是表达式右侧(的主体h1)中使用的占位符。这里参数的相对顺序只是告诉我们如何调用h1,但没有告诉我们如何h1在内部使用参数。
同样,这是一个程序样式的等价物(我将使用 Python,因此不必填写任何类型):
def h1(f, g, x, y):
return f(g(x,y),x)
这意味着与
h1 f g x y = f (g x y) x
(有一个警告 - 部分应用 - 我怀疑只会在这里进一步混淆问题)。
在这两种情况下,声明(=在 Haskell 中的左侧,:在 Python 中的之前)只告诉我们函数名称和它需要多少个参数。
在这两种情况下,我们可以从定义(Haskell 中的右侧,Python 中的缩进块)推断出和都是两个参数的函数,第一个参数与第二个参数相同,等等。在 Haskell ,编译器为我们做这件事;如果我们使用错误数量的参数调用,Python 只会在运行时抱怨,或者它返回的东西不能用作第一个参数。:fggfgf