Haskell中的函数类型推断

csj*_*csj 6 haskell

我在为Haskell做练习问题,问题之一是

test3 x y = x (x y)
Run Code Online (Sandbox Code Playgroud)

为此,我必须找到类型。

解决方法是

test3 :: (a -> a) -> a -> a
Run Code Online (Sandbox Code Playgroud)

我不明白为什么解决方案中的变量都是a,而不是将x和y称为两个不同的变量,例如a和b。有人可以解释一下,还可以找到如何找到此问题的类型。

Rob*_*ond 20

实际上,这是一个非常有趣的练习。它不需要任何有关Haskell的知识-实际上,这只是基本逻辑。

test3 x y = x (x y)
Run Code Online (Sandbox Code Playgroud)

首先要注意的是,它test3接受2个参数(xand和y)并产生某种结果。所以类型必须是形式

a -> b -> c
Run Code Online (Sandbox Code Playgroud)

它不仅仍然要弄清楚什么ab以及c是,或者至少它们之间存在什么关系。

因此,让我们x (x y)更详细地检查该结果。它告诉我们这x是一个可以y作为参数的函数。我们已经说过,它y具有类型b(这是一个完全任意的名称,但现在让我们继续使用它)-因此x必须是一个带有a b并产生某种类型结果的函数。d现在,我们将该类型称为。因此,我们知道的类型test3的形式为

(b -> d) -> b -> c
Run Code Online (Sandbox Code Playgroud)

最后,再次从表达式中x (x y),我们看到它x必须采用x y-我们已经为类型指定d-并返回结果。这个结果是的总体结果test3,我们选择了它的类型c。因此,在上面,x我们已经为其分配了类型b -> d,必须具有type d -> c。唯一b -> d可以等于的方法d -> c是if bc并且d都是相同的类型。(因为函数的类型取决于它们的输入类型和结果类型。)因此的总体类型test3必须为以下形式:

(b -> b) -> b -> b
Run Code Online (Sandbox Code Playgroud)

这正是您被告知的-改名ab。(正如我所说,名称是任意的,因此不相关。)