2013-05-19 8 views
6

PowiedzmyJak to wyliczenie rodzajów w Haskell

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

typ (odwrotną const) byłoby

a=d,b=e,c=d 

w

b->a->c 

więc rodzaj byłoby

e->d->d 

Ale do startu (mapa) jego

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

więc nie rozumiem, w jaki sposób ghci ten oblicza. zrozumiałem [[a]] -> [[a]], ale dlaczego i jak [Int]?

edit: Na przykład, jeśli chcemy pisać w ghci

:t flip const 


it would return b->c->c 

i ghci by obliczyć, że jak ja.

Ale

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

więc dlaczego jest mapa wziąć

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

dlaczego [Int] W jaki sposób ghci obliczyć, że

+6

To jest "[Int] -> [[a] -> [a]]", a nie "[Int] -> [[a]] -> [[a]]". Zwróć uwagę na różnicę w nawiasach kwadratowych. –

Odpowiedz

12

Powinieneś skopiować i wkleić typy, które widzisz, a nie ponownie wpisać je w pytanie. Powodem jest, że widziałeś coś złego. Typ dla map take jest:

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

Innymi słowy, zjednoczenie działa jako takie:

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

więc przy stosowaniu take jako pierwszy argument do map masz a ~ Int i b ~ [c] -> [c] (Zauważ, że jest funkcjonować). Wykonywanie tych zamienników w rodzaju map i stosowaniu pierwszego argumentu:

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 jest dokładnie to, czego można się spodziewać.Funkcja działająca na listach Ints i wyświetlająca listę funkcji, które zajmą pewną liczbę elementów od początku listy.

+0

Czy ma to nazwę tematu w haskell? Szukałem "unifikacji typu haskell", ale nie znalazłem nic istotnego. – 7stud

+1

"Inferencja typu" jest prawdopodobnie Twoim najbardziej przydatnym terminem. –

+2

Jest to bardzo trafne https://docs.google.com/file/d/1oTZkzY1MiQwUAdoW3E5Fsb7p6AYRU4ph9BrR17TC-Qrzh-6vHUS6mRatgZhL/edit?usp=sharing – Wes

14

Zróbmy taką samą analizę:

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

I

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

Ale to faktycznie oznacza

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

Więc z a=Int i b=([x] -> [x]) masz

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

listę funkcji lista!