简体   繁体   English

了解 Haskell 中的类型(lambda 表达式和高阶函数)

[英]Understanding types in Haskell (lambda epxressions and higher order functions)

I'm currently doing a course in Haskell, and I have a lot of difficulty understanding the types of functions, particularly when there's function application or lambda expressions.我目前正在上 Haskell 的课程,我很难理解函数的类型,特别是当有 function 应用程序或 lambda 表达式时。 Say for instance the following:例如说以下内容:

f = (\x -> \y -> \z -> [x (y z), y z])

or或者

g = \x -> \y -> \z -> x.y.z

I can sort of make some assumptions about the fact that x and y are functions, but I don't have a concrete method for figuring out the types of these functions.我可以对xy是函数这一事实做出一些假设,但我没有具体的方法来确定这些函数的类型。

Similarly for the following:以下类似:

h = foldr (&&)

I try to guess and then check via :t in the interpreter, but I'm usually off by quite a bit.我尝试猜测,然后在解释器中通过:t检查,但我通常会偏离很多。 Is there any particular method I can use to find the types of such functions?我可以使用任何特定方法来查找此类函数的类型吗?

You start by assigning type variables to the inputs and the result您首先将类型变量分配给输入和结果

f = (\x -> \y -> \z -> [x (y z), y z])

and conclude并得出结论

f :: a -> b -> c -> d   --  (A0)
-- or even (f is not needed)
\x -> \y -> \z -> [x (y z), y z] :: a -> b -> c -> d

that is那是

x :: a                -- (1)
y :: b                -- (2)
z :: c                -- (3)
[x (y z), y z] :: d   -- (4)

You can continue with (4) and conclude您可以继续(4)并得出结论

  • that the type d is a list of d1 s, ie d ~ [d1] (5)类型dd1的列表,即d ~ [d1] (5)

     f:: a -> b -> c -> [d1] -- (A1)
  • and that the values of the list are of type d1 , ie并且列表的值属于d1类型,即

    x (yz):: d1 -- (6) yz:: d1 -- (7)

From (6) you learn that(6)你了解到

x :: e -> d1   -- (8)
y z :: e       -- (9)

(1) and (8) unify, ie a ~ (e -> d1) and (1)(8)统一,即a ~ (e -> d1)

f :: (e -> d1) -> b -> c -> [d1] -- (A2)

You play this game until you get bored and use GHCi to arrive at你玩这个游戏直到你感到无聊,然后使用GHCi到达

f :: (d1 -> d1) -> (f -> d1) -> f -> [d1] -- (A3)
-- and renaming
f :: (a -> a) -> (b -> a) -> b -> [a]     -- (A4)

If you want to learn more and read a paper you can start with Principal type-schemes for functional programs .如果您想了解更多信息并阅读论文,您可以从函数式程序的 Principal type-schemes开始。

Prelude> :t h
h :: Foldable t => Bool -> t Bool -> Bool
Prelude> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
Prelude> :t (&&)
(&&) :: Bool -> Bool -> Bool
Prelude> 

By "plugging in" (&&) you have removed (a -> b -> b) so you need to provide the rest to the function通过“插入”(&&),您已删除(a -> b -> b) ,因此您需要将 rest 提供给 function

b -> t a -> b

That is restricted by (&&) to be a bool as second param to it, and the second parameter is the ta which is also restricted to being a bool.这受(&&)限制为 bool 作为它的第二个参数,第二个参数是ta ,它也被限制为 bool。 since a and b needs to be the same type as in the (a->b->b) function.因为 a 和 b 需要与(a->b->b) function 中的类型相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM