2013-05-08 17 views
14

Rozważ funkcję preludium words; to jest bardzo proste i można napisać go w następujący sposób:Dlaczego funkcja słów Preludium nie jest prostsza?

words' :: String -> [String] 
words' [] = [] 
words' str = before : words' (dropWhile isSpace after) where 
    (before, after) = break isSpace str 

Jednak zauważyłem, że jej oryginalny kod Prelude wydaje się o wiele mniej ... naturalne:

words     :: String -> [String] 
words s     = case dropWhile {-partain:Char.-}isSpace s of 
           "" -> [] 
           s' -> w : words s'' 
             where (w, s'') = 
              break {-partain:Char.-}isSpace s' 

Zakładam, że istnieją przyczyny związane z optymalizacją. Pytanie brzmi: czy nie mogę się spodziewać, że kompilator powinien zoptymalizować funkcję words' tak samo dobrze, jak jej wersję Prelude? Użyłem tych samych funkcji (break, dropWhile, isSpace).

byłem kiedyś bardzo zaskoczony, że GHC nie wykonywać niektóre z najprostszych optymalizacje niskopoziomowych:

C vs Haskell Collatz conjecture speed comparison

ale na bok dla {-partain:Char.-} bitów (wskazówka dla kompilatora nie wydaje się bardzo pomocne w ta sytuacja IMO) kod words wydaje się niepotrzebnie nadęty dla języka wysokiego poziomu. Jaki jest tego powód?

+5

Nie sądzę, że bit '{-partain: Char .-}' jest czymś więcej niż komentarzem do nazwy modułu, przy okazji. Według Google, ktoś o nazwisku Partain pracował nad GHC jakiś czas temu. Zgaduję, że to tylko on podpisał swoje komentarze. – hammar

+0

Och, myślałem, że to mogło mieć jakiś wpływ na kompilator. Fajny połów z Partainem! – ljedrz

+2

To będzie Partain. – augustss

Odpowiedz

12

To prawie dokładnie ten sam kod. Jedyna różnica polega na tym, że robimy dropWhile isSpace przed każdym wywołaniem lub tylko z wywołaniem rekursywnym. Nie jest ona bardziej złożona niż druga, ale raczej ta druga wersja (Prelude) wydaje się bardziej szczegółowa, ponieważ dopasowywanie wzorca nie jest bezpośrednio w funkcji.

można zaobserwować różnicę (i dlaczego wersja Prelude ma lepsze zachowanie) tak:

*Main> words " " 
[] 
*Main> words' "  " 
[""] 

pamiętać, że można szybko sprawdzić, czy twoje „ulepszone” wersje są takie same jak oryginały korzystających QuickCheck.

+0

Cóż, nie sądzę, że moja wersja jest w jakikolwiek sposób lepsza niż oryginał, ale o to właśnie chodzi; dla mnie wydawało się, że jedyną różnicą była gadatliwość. – ljedrz

+0

Miałem inne spojrzenie w 'Prelude' i kilku innych podstawowych bibliotekach i muszę powiedzieć, że gadatliwość jest w rzeczywistości dość rzadka w definicjach funkcji (i prawdopodobnie jest wyjaśniona przez przypadki takie, jak opisane). Pierwotny tytuł pytania był przesadą :). – ljedrz

Powiązane problemy