2013-05-02 24 views
6

Jako początkujących do Haskell Nie mogę zrozumieć, dlaczego wyrażenie head . words “one two three four” zgłasza wyjątek i składu function head . words muszą być stosowane z $ operator - wyraz po prawej stronie nie ma Potrzebujemy dalszej oceny, ponieważ jest to tylko jeden numer String. Innym sposobem kompilacji jest wstawienie head . words w nawiasach, ale (head . words) :: String -> String ma ten sam typ co head . words :: String -> String, więc dlaczego umieszczenie go w nawiasach powoduje kompilację wyrażenia?Stosowanie argumentów funkcjonowała w składzie Haskell

Odpowiedz

11

Z powodu zasad pierwszeństwa. Aplikacja ma najwyższy priorytet; $ - najniższy.

head . words “one two three four” jest analizowany jako head . (words “one two three four”) tj words nałożonego na sznurkiem musi uzyskania funkcji (zgodnie z wymaganiami (.)). Ale to nie jest typem, który words posiada:

Prelude> :t words 
words :: String -> [String] 

head . words $ “one two three four” Z drugiej strony, jest analizowany jako (head . words) “one two three four” oraz rodzaje pasuje.

+0

Dzięki za odpowiedź, było mi trochę trudno zrozumieć, że operator kompozycji sam w sobie jest funkcją. –

+2

@wojtek ah, tak, '(.) :: (b -> c) -> (a -> b) -> a -> c'. Nie zapominaj, że strzałki w podpisach typu kojarzą się z prawą. To naprawdę '(.) :: (b -> c) -> (a -> b) -> (a -> c)'. Wyobraź sobie, że masz te dwie rury: 'g :: b-> c' i' h :: a-> b'. Więc oczywiście, wyjście 'b' przechodzi do wejścia' b': '(g.h) x = g (hx)' to znaczy '(g.h) :: a-> c'. –

+1

@wojtek Każdy operator sam w sobie jest funkcją i ma niższy priorytet niż zastosowanie funkcji. Jest to coś, o czym programista Haskell absolutnie musi pamiętać. – Ingo