简体   繁体   中英

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. 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.

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. 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

  • that the type d is a list of d1 s, ie d ~ [d1] (5)

     f:: a -> b -> c -> [d1] -- (A1)
  • and that the values of the list are of type d1 , ie

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

From (6) you learn that

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

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

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

You play this game until you get bored and use GHCi to arrive at

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 .

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

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. since a and b needs to be the same type as in the (a->b->b) function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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