2013-05-08 3 views
14

Considerare la funzione di preludio words; è davvero facile e si potrebbe scrivere nel modo seguente:Perché la funzione di parole del Preludio non è scritta più semplicemente?

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

Tuttavia, ho notato che il suo codice Prelude originale sembra molto meno ... naturale:

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

Suppongo che ci sono ragioni di ottimizzazione per esso. La domanda è: ho sbagliato aspettarmi che il compilatore debba ottimizzare la funzione words' altrettanto bene della sua versione Prelude? Ho usato le stesse funzioni (break, dropWhile, isSpace).

Una volta ero molto sorpreso che GHC non ha svolto alcune delle più semplici ottimizzazioni di basso livello:

C vs Haskell Collatz conjecture speed comparison

ma da parte per le {-partain:Char.-} bit (questo suggerimento per il compilatore non sembra molto utile questa situazione IMO) il codice words sembra inutilmente gonfio per un linguaggio di alto livello. Qual è la ragione dietro a questo in questo caso?

+5

Non penso che il bit '{-partain: Char .-}' sia qualcosa di più di un nome di un modulo commentato, a proposito. Secondo Google, qualcuno con il cognome Partain ha lavorato su GHC qualche tempo fa. Immagino che fosse solo lui a firmare i suoi commenti. – hammar

+0

Oh, ho pensato che avrebbe potuto influenzare il compilatore. Bella cattura con il ragazzo Partain! – ljedrz

+2

Questo Will Partain. – augustss

risposta

12

Questo è quasi esattamente lo stesso codice. L'unica differenza è se stiamo facendo il dropWhile isSpace prima di ogni chiamata o solo la chiamata ricorsiva. Nessuno dei due è più complesso dell'altro, ma la seconda versione (Preludio) sembra più dettagliata perché la corrispondenza del modello non è direttamente nella funzione.

È possibile osservare la differenza (e perché la versione Preludio ha una migliore comportamento) in questo modo:

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

Si noti che è possibile verificare rapidamente se le vostre versioni "migliorate" sono gli stessi degli originali utilizzando QuickCheck.

+0

Beh, non penso che la mia versione sia in alcun modo migliore dell'originale, ma questo è il punto; a me sembrava che l'unica differenza fosse la verbosità. – ljedrz

+0

Ho avuto un altro aspetto in 'Prelude' e alcune altre librerie di base e devo dire che la verbosità è in effetti abbastanza rara nelle definizioni di funzione (ed è probabilmente spiegata da casi come quello che hai descritto). Il titolo della domanda originale era un'esagerazione :). – ljedrz