Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 455
ProgrammerPotato Avatar asked May 19 '13 17:05

ProgrammerPotato


People also ask

How does type determine in Haskell?

If you need to figure out what the type of an object is in a Haskell program, I hope this is helpful. Note that if you are in GHCI, you can just put :type before your expression to determine the expression's type, or use :set +t to see the type of every expression in GHCI.

How do you create a type in Haskell?

In Haskell, you can create new type synonyms by using the type keyword.

What is the Haskell type system?

Haskell is a statically typed language. Every expression in Haskell has a type, including functions and if statements. The compiler can usually infer the types of expressions, but you should generally write out the type signature for top level functions and expressions.


2 Answers

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!

like image 196
AndrewC Avatar answered Oct 19 '22 20:10

AndrewC


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.

like image 12
Thomas M. DuBuisson Avatar answered Oct 19 '22 18:10

Thomas M. DuBuisson