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 来找到答案,但是如何找到这个答案?我从我之前的帖子中了解到,它与 lambda 函数有关,但我无法解释这里发生了什么。

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

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

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

4

2 回答 2

6

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

(x y, x (x z))

因为x被应用于事物(yzx z),所以我们知道它具有(a -> ?)问号表示未知类型的类型。现在, 的结果x被传递给xin x (x z),所以它的输入类型必须是它的输出类型:

x :: a -> a

现在,x应用于yz,所以它们都必须是 类型ax 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对于你的第二个问题,让我们先看看在's 的定义中哪些东西与哪些变量绑定。第一个参数是 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])
于 2012-06-20T19:16:14.623 回答
1

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

注意最后的应用程序。x 应用于 y,所以 x 必须是一个函数。x 也适用于 (xz),因此 x 必须返回与它作为参数相同的类型。

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

编辑:所以,t3 只是 t2 应用于参数(取 3 . reverse) mnr mnr。第一个参数是 t2 中的 x,我们在上面看到 x 应用于 y,然后应用于 (xz)。

那么结果就是((take 3 . reverse) mnr, (take 3 . reverse) ((take 3 . reverse) mnr))

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

于 2012-06-20T19:02:21.743 回答