ProgrammerPotato
ProgrammerPotato

Reputation: 515

How is the calculation of types in Haskell

Lets say

  flip :: (a->b->c) ->b->a->c
  const ::d->e->d

type of (flip const) would be

  a=d,b=e,c=d

in

  b->a->c

so the type would be

  e->d->d

But for (map take) its

  [Int]->[[a]]->[[a]]

so i didn't understand how the ghci this one calculated. i understood the [[a]]->[[a]] but why and how [Int] ?

edit: For example if we'd write in ghci

  :t flip const 


it would return b->c->c

and ghci would calculate that as i did.

But

 map :: (a->b)->[a]->[b]
 take :: Int->[c]->[c]

so why is map take

  [Int]->[[a]->[a]]

why [Int] how did the ghci calculate that

Upvotes: 7

Views: 509

Answers (2)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

You should copy and paste the types you see, not re-type them into the question. The reason is you saw wrong. The type for map take is:

map take :: [Int] -> [[a] -> [a]]

In other words, the unification works as such:

:t map
map :: (a -> b) -> [a] -> [b]
:t take
take :: Int -> [c] -> [c]

so when applying take as the first argument to map you get a ~ Int and b ~ [c] -> [c] (notice that is a function). Performing these replacements in the map type and applying the first argument:

map take :: [a] -> [b]        (for some specific 'a' and 'b')
-- recall a ~ Int
map take :: [Int] -> [b]      (for some specific 'b')
-- recall b ~ [c] -> [c]
map take :: [Int] -> [[c] -> [c]]

Yay, map take is exactly what you expect. A function that operates over lists of Ints and results in a list of functions that will take some number of elements from the start of a list.

Upvotes: 12

AndrewC
AndrewC

Reputation: 32455

Let's do the same analysis:

map :: (a -> b) -> [a] -> [b]

And

take :: Int -> [x] -> [x]

But that actually means

take :: Int -> ([x] -> [x])

So with a=Int and b=([x] -> [x]) you get

map take :: [Int] -> [ [x] -> [x] ]

A list of list functions!

Upvotes: 15

Related Questions