2012-01-20 14 views
11

ho letto questo:ViewPatterns e più chiamate a Haskell

http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns

Mi piace l'idea, vuole utilizzare l'estensione. Vorrei tuttavia accertarmi di una cosa: se la funzione di visualizzazione viene valutata una sola volta per una singola corrispondenza.

Quindi diciamo che abbiamo:

Ora diciamo che invoco f a. view invocato due volte o solo una volta per l'argomento specificato a?

EDIT:

ho cercato di scoprire se questo è il caso e ha scritto quanto segue:

{-# LANGUAGE ViewPatterns #-} 

import System.IO.Unsafe 

blah (ble -> Nothing) = 123 
blah (ble -> Just x) = x 

ble x = unsafePerformIO $ do 
    putStrLn $ "Inside ble: " ++ show x 
    return x 

main :: IO() 
main = do 
    putStrLn $ "Main: " ++ show (blah $ Just 234) 

output utilizzando GHC:

Inside ble: Just 234 
Inside ble: Just 234 
Main: 234 

output utilizzando GHC (con ottimizzazione)

Inside ble: Just 234 
Main: 234 

uscita utilizzando GHCi:

Main: Inside ble: Just 234 
Inside ble: Just 234 
234 
+0

GHC ha un hack speciale per evitare il ricalcolo di identiche espressioni di visualizzazione. – augustss

risposta

13

Solo una volta:

Efficienza: Quando la stessa funzione di visualizzazione è applicata in diversi rami di una definizione di funzione o un'espressione caso (ad esempio, in size sopra), GHC tenta di raccogliere queste applicazioni in una singola espressione del caso annidato, in modo che la funzione vista sia applicata solo una volta. La compilazione dei pattern in GHC segue l'algoritmo di matrice descritto nel Capitolo 4 di The Implementation of Functional Programming Languages. Quando le righe superiori della prima colonna di una matrice sono tutti i modelli di vista con la stessa espressione "uguale" , questi modelli vengono trasformati in un caso nidificato . Questo include, per esempio, vedi adiacenti modelli che risultano allineati in una tupla, come in

 
f ((view -> A, p1), p2) = e1 
f ((view -> B, p3), p4) = e2 

L'attuale nozione di quando due espressioni vista del modello sono "la stesso" è molto ristretto: non è nemmeno pieno uguaglianza sintattica. Tuttavia, include variabili, letterali, applicazioni e tuple; , ad esempio, due istanze di view ("hi", "there") saranno raccolte. Tuttavia, l'implementazione corrente non viene confrontata con l'equivalenza alfa , quindi due istanze di (x, view x -> y) non verranno combinate.

- The GHC manual

Per quanto riguarda il tuo snippet, il problema è che non sta compilando con l'ottimizzazione; con sia ghc -O e ghc -O2, la linea viene stampata una sola volta.Questo è sempre la prima cosa da controllare quando si hanno problemi relativi alle prestazioni quando si utilizza GHC :)

(A proposito, Debug.Trace permette di controllare questo genere di cose, senza dover scrivere manuali unsafePerformIO hack.)

+0

È possibile che GHC stia inserendo ulteriori valutazioni di riserva a causa di performUnsafeIO? Non preoccuparti, l'ho usato solo per testare la funzione. – julkiewicz

+0

Ho aggiunto un esempio di codice concreto. – julkiewicz

+0

@julkiewicz: Ho aggiornato la mia risposta :) – ehird

Problemi correlati