Haskell:确定函数类型

时间:2012-06-20 18:54:06

标签: haskell functional-programming

在学习功能编程考试时,我在之前的测试中遇到了以下问题:

t2 = (\x -> \y -> \z -> (x y, x (x z)))

t3 = t2 (take 3 . reverse) mnr mnr

对于t2,要求确定该语句的最一般类型。答案似乎是:

(a -> a) -> a -> a -> (a,a)

我可以通过在WinHugs中输入声明来找到答案,但是如何找到答案?我从previous post了解到它与lambda函数有关,但除此之外我无法解释这里发生的事情。

问题的第二部分(t3)然后将两个函数应用于变量mnr的两个实例。对于mnr = [0,1,2,3,4,5,6],结果如下:

([6,5,4],[4,5,6])

这是如何工作的?函数take和reverse是清楚的,但它们如何应用于t2中的lambda函数?

2 个答案:

答案 0 :(得分:6)

让我们从中间开始,结果。

(x y, x (x z))

因为x被应用于事物(yzx z),我们知道它的类型(a -> ?)带有问号代表一种未知类型。现在,x的结果将传递给x中的x (x z),因此其输入类型必须是其输出类型:

x :: a -> a

现在,x已应用于yz,因此它们都必须属于a类型。 x yx (x z)也属于a类型(因为它是x的返回类型),因此t2会返回(a, a)类型的内容}。

将它与其参数的类型(xyz)放在一起,我们得到的是类型

(a -> a) -- x's type
-> a -- y's type
-> a -- z's type
-> (a, a) -- the result type

对于第二个问题,让我们首先看一下t2定义中哪些变量与哪些变量绑定。第一个参数是x,所以在这种情况下

x = (take 3 . reverse)

下一个参数是y,所以

y = mnr

同样适用于z,

z = mnr

结果将是(x y, x (x z)),所以让我们评估一下

(x y, x (x z))
= ((take 3 . reverse) mnr, (take 3 . reverse) ((take 3 . reverse) mnr))
= (take 3 (reverse mnr), take 3 (reverse (take 3 (reverse mnr))))

对于mnr = [0,1,2,3,4,5,6]的特定情况,我们得到了

= (take 3 (reverse [0,1,2,3,4,5,6]), take 3 (reverse (take 3 (reverse [0,1,2,3,4,5,6]))))
= (take 3 [6,5,4,3,2,1,0], take 3 (reverse (take 3 [6,5,4,3,2,1,0])))
= ([6,5,4], take 3 (reverse [6,5,4]))
= ([6,5,4], take 3 [4,5,6])
= ([6,5,4], [4,5,6])

答案 1 :(得分:1)

  

t2 =(\ x - > \ y - > \ z - >(x y,x(x z)))

注意最后的申请。 x应用于y,因此x必须是函数。 x也适用于(x z),因此x必须返回与参数相同的类型。

我不确定你对第二个问题的意思。 mnr的两个实例?

编辑: 因此,t3只是t2应用于参数(取3。反向)mnr mnr。第一个参数是在t2中被称为x,我们在上面看到x被应用于y然后(x z)。

结果是((take 3 . reverse) mnr, (take 3 . reverse) ((take 3 . reverse) mnr))

元组的第一部分中的mnr是作为参数(y)传递的第一个mnr。第二部分中的一个是第二个参数(z)。当然,它们是一样的。