2014-05-08 83 views
0

我正在学习一些Haskell,我无法理解一些东西。我有这样的表达:Haskell表达式类型?

flip foldr id 

而我需要找到它的类型。经过漫长的时间来解决这个问题,我放弃了,抬头一看正确的答案,那就是:

(a -> (a1 -> a1) -> a1 -> a1) -> [a] -> a1 -> a1 

但我不明白为什么,我想! 我想[a] -> a1 -> a1来自foldr表达式,但我不知道如何继续。 谢谢,对不起我的英文!

回答

6

检查类型所涉及的各个功能:

λ :t id 
id :: a -> a 
λ :t foldr 
foldr :: (a -> b -> b) -> b -> [a] -> b 
λ :t flip 
flip :: (a -> b -> c) -> b -> a -> c 

然后尝试应用功能彼此怎么看的类型,将匹配的思考。

为避免名称冲突,我们可以将flip的类型改写为(a1 -> b1 -> c1) -> b1 -> a1 -> c1

发生的第一件事是将flip应用于foldr。查看flipfoldr的类型,我们看到flip类型中的a1 -> b1 -> c1类型与foldr类型得到“匹配”。这意味着a1a -> b -> b匹配,b1b匹配,而c1[a] -> b匹配。

因此,在这样的背景下,flip的类型变得((a -> b -> b) -> b -> [a] -> b) -> b -> (a -> b -> b) -> [a] -> b(我刚刚更换每个a1a -> b -> c,每个b1b,每个c1[a] -> b),以及flip foldr类型是与第一同样的事情带走参数:b -> (a -> b -> b) -> [a] -> b

我们可以用ghci中迄今检查我们的工作:

λ :t flip foldr 
flip foldr :: b -> (a -> b -> b) -> [a] -> b 

现在我们采取这种类型的,它适用于id类型(我们将写成a2 -> a2)。这意味着ba2 -> a2匹配,并且flip foldr的类型变为(a2 -> a2) -> (a -> (a2 -> a2) -> (a2 -> a2)) -> [a] -> (a2 -> a2)flip foldr id的类型与第一个参数带走的类型相同:(a -> (a2 -> a2) -> (a2 -> a2)) -> [a] -> a2 -> a2。如果我们将a2重写为a1并删除一些括号,则这与您得到的答案相同。

+0

我不明白应用哪个函数。 – DemianArdus

+0

在'flip foldr id'中,'foldr'和'id'作为第一个和第二个参数传递给'flip',或者'id'作为参数传递给'flip foldr'的结果。 – Cirdec

+0

@DemianArdus函数应用程序是左关联的,所以这意味着''flip foldr id'与'(flip foldr)id'相同。由于函数应用程序在haskell中的工作方式,这就像'foldr'和'id'都被传递给'flip'。 – Alec