在学习功能编程考试时,我在之前的测试中遇到了以下问题:
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函数?
答案 0 :(得分:6)
让我们从中间开始,结果。
(x y, x (x z))
因为x
被应用于事物(y
,z
和x z
),我们知道它的类型(a -> ?)
带有问号代表一种未知类型。现在,x
的结果将传递给x
中的x (x z)
,因此其输入类型必须是其输出类型:
x :: a -> a
现在,x
已应用于y
和z
,因此它们都必须属于a
类型。 x y
和x (x z)
也属于a
类型(因为它是x
的返回类型),因此t2
会返回(a, a)
类型的内容}。
将它与其参数的类型(x
,y
和z
)放在一起,我们得到的是类型
(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)。当然,它们是一样的。