2013-02-21 7 views
6

In F # Interactive (fsi), è possibile utilizzare AddPrinter o AddPrinterTransformer per fornire una bella stampa per un tipo nella sessione interattiva. Come posso aggiungere una stampante di questo tipo per un tipo generico? Utilizzando il carattere jolly _ per il tipo non funziona:Come si aggiunge una stampante carina per un tipo generico a fsi?

> fsi.AddPrinter(fun (A : MyList<_>) -> A.ToString());; 

La stampante semplicemente non viene utilizzato.

Mettere in un parametro di tipo dà anche un avvertimento:

> fsi.AddPrinter(fun (A : MyList<'T>) -> A.ToString());; 

    fsi.AddPrinter(fun (A : MyList<'T>) -> A.ToString());; 
    -------------------------------^^ 

d:\projects\stdin(70,51): warning FS0064: This construct causes code 
to be less generic than indicated by the type annotations. The type 
variable 'T been constrained to be type 'obj'. 

che non è quello che voglio, neanche.

+2

Sono abbastanza sicuro che questo non è possibile. Un argomento di tipo richiede un tipo concreto. – Daniel

+0

Puoi sovrascrivere 'ToString' per' MyList <'T> '? – Daniel

risposta

7

Questo non funzionerà nel caso generale, ma dal momento che sembra che tu stia lavorando con il tuo tipo (almeno nel tuo esempio), e assumendo che non vuoi influenzare ToString, potresti fare qualcosa come questo:

type ITransformable = 
    abstract member BoxedValue : obj 

type MyList<'T>(values: seq<'T>) = 
    interface ITransformable with 
    member x.BoxedValue = box values 

fsi.AddPrintTransformer(fun (x:obj) -> 
    match x with 
    | :? ITransformable as t -> t.BoxedValue 
    | _ -> null) 

uscita:

> MyList([1;2;3]) 
val it : MyList<int> = [1; 2; 3] 

per un tipo generico di terze parti è possibile utilizzare AddPrintTransformer e la riflessione per ottenere il valore da visualizzare. Un'interfaccia è più semplice se hai la fonte.

+0

Grazie. Ma perché dichiarate il parametro 'AddPrintTransformer' per avere il tipo' obj'? Perché non usare 'ITransformable' direttamente lì? O anche usare 'AddPrinter' con una funzione che prende un' ITransformabile'? –

+0

È 'obj' perché ho iniziato per la prima volta a usare il riflesso. Probabilmente puoi cambiarlo in 'ITransformable'. Penso che 'AddPrintTransformer' sia migliore per quello che stai cercando di fare perché, nella maggior parte dei casi, la delega a un valore visualizzabile è sufficiente. – Daniel

Problemi correlati