2012-06-20 92 views
0

在研究了函数式编程考试,我碰到以下问题来自于以前的测试:哈斯克尔:确定功能类型

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]) 

这是如何工作的?函数采用和反向都很清楚,但它们在t2中如何应用于lambda函数?

回答

6

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

(x y, x (x z)) 

因为x被应用到的东西(yzx z),我们知道它具有类型(a -> ?)其中问号代表未知类型。现在,x结果被传递给xx (x z),所以它的输入的类型必须是它的输出类型:现在

x :: a -> a 

x被施加到yz,所以它们两者都必须是a类型的。 x yx (x z)也都是a(因为它是x的返回类型),因此t2返回(a, a)类型的内容。

与它的参数(xy,并且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]) 
+0

令人惊叹的答案,谢谢你一步步走过我。 –

1

T2 =(\ X - > \ý - > \ž - >(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)。当然,他们是一样的。

+0

t3 = t2(取3。反向)mnr mnr - mnr有两次。也许那些不叫做“实例” - 我不确定。正如你所看到的,我对Haskell并不擅长。 –