Hyb*_*tem 0 haskell functional-programming
在学习功能编程考试时,我从之前的测试中发现了以下问题:
t2 = (\x -> \y -> \z -> (x y, x (x z)))
t3 = t2 (take 3 . reverse) mnr mnr
Run Code Online (Sandbox Code Playgroud)
对于t2,要求它确定语句的最一般类型.答案似乎是:
(a -> a) -> a -> a -> (a,a)
Run Code Online (Sandbox Code Playgroud)
我可以通过在WinHugs中输入声明来找到答案,但是如何找到答案呢?我从之前的帖子中了解到它与lambda函数有关,但除此之外我无法解释这里发生了什么.
然后问题的第二部分(t3)将两个函数应用于变量mnr的两个实例.对于mnr = [0,1,2,3,4,5,6],这会导致:
([6,5,4],[4,5,6])
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?函数take和reverse是清楚的,但它们如何应用于t2中的lambda函数?
让我们从中间开始,结果.
(x y, x (x z))
Run Code Online (Sandbox Code Playgroud)
因为x正在应用于事物(y,z和x z),我们知道它具有(a -> ?)问号代表未知类型的类型.现在,结果x传递给xin x (x z),所以它的输入类型必须是它的输出类型:
x :: a -> a
Run Code Online (Sandbox Code Playgroud)
现在,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
Run Code Online (Sandbox Code Playgroud)
对于你的第二个问题,让我们首先看看t2与定义中的变量有什么关系.第一个参数是x,所以在这种情况下
x = (take 3 . reverse)
Run Code Online (Sandbox Code Playgroud)
下一个参数是y,所以
y = mnr
Run Code Online (Sandbox Code Playgroud)
同样对于z,
z = mnr
Run Code Online (Sandbox Code Playgroud)
结果将是(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))))
Run Code Online (Sandbox Code Playgroud)
有了这个特例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])
Run Code Online (Sandbox Code Playgroud)