2010-10-03 2 views
31

sulla mailing list Agda, Conor McBride ha chiesto:coerce Unsafe e codice più efficiente Agda (-ftrust-me-im-agda)

c'è un modo per entrare in possesso di operazioni come un putativo

trustFromJust :: Maybe x -> x 

che in realtà non controlla Just and Goes Wrong (in Milner's senso) se alimentato Nothing?

Agda potrebbe provare Forse a == Just1 a, e il costruttore intermedio per il tipo di somma potrebbe essere eliminato.

Posso pensare ad approcci che usano unsafeCoerce # o unpackClosure #, ma qualcun altro ha pensieri?

import GHC.Prim 

trustFromJust :: Maybe x -> x 
trustFromJust x = y 
    where Just1 y = unsafeCoerce# x 

data Just1 a = Just1 a 

sebbene questo segfaults (i singoli tipi di costruttore possono evitare parte dell'overhead di chiusura). Il nucleo sembra ok se:

main2 = 
    case (Data.Maybe.Just @ Type.Integer main3) 
     `cast` 
     (CoUnsafe 
     (Data.Maybe.Maybe Type.Integer) 
     (Just1 Type.Integer) 
       :: Data.Maybe.Maybe Type.Integer 
        ~ 
        Just1 Type.Integer) 
    of _ { Just1 y_aeb -> 
    $wshowsPrec 0 y_aeb ([] @ Char) 
+0

È interessante notare che il codice viene eseguito in GHCi. Sebbene sia effettivamente segfault durante la sua compilazione. –

+1

Forse ha 'Just' come costruttore di seconda lista, e Just1 ha' Just1' come prima - non significa che otterranno diversi offset di ritorno del vettore thunk? E in entrambi i casi, dovendo costruire una finestra 'Maybe' solo per decomprimere, sembra che avrebbe lo stesso sovraccarico, non importa se lo spacchetti usando unsafeCoerce o da Just, vero? – mokus

+0

Se si aggiunge un costruttore fittizio davanti al costruttore 'Just1',' unsafeCoerce # 'non darà come risultato un segfault. Non lo so perché è perché gli offset ora corrispondono o anche perché il tipo di dati ora è anche un tipo di somma. –

risposta

6

Poiché si tratta di una domanda di ricerca, abbiamo alcuni modi possibili in avanti, ma tutti scendono a:

  • trucchi Giocare invertendo i bit indicatori di Forse