2013-02-21 13 views
6

In F # Interactive (fsi) können Sie AddPrinter oder AddPrinterTransformer verwenden, um in der interaktiven Sitzung einen hübschen Ausdruck für einen Typ bereitzustellen. Wie kann ich einen solchen Drucker für einen generischen Typ hinzufügen? Unter Verwendung des Wildcard _ für den Typ nicht funktioniert:Wie füge ich einen hübschen Drucker für einen generischen Typ zu fsi hinzu?

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

Der Drucker ist gerade nicht verwendet wird.

in einem Typ-Parameter Putting gibt auch eine Warnung:

> 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'. 

was nicht, was ich will, auch nicht.

+2

Ich bin mir ziemlich sicher, dass das nicht möglich ist. Ein Typ arg erfordert einen konkreten Typ. – Daniel

+0

Können Sie 'ToString' für' MyList <'T> 'überschreiben? – Daniel

Antwort

7

Dies funktioniert nicht für den allgemeinen Fall, aber da es scheint, dass Sie mit Ihrem eigenen Typ arbeiten (zumindest in Ihrem Beispiel), und davon ausgehen, dass Sie ToString nicht beeinflussen möchten, könnten Sie etwas tun dies:

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) 

Ausgang:

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

Für einen Drittanbieter generischer Typ Sie AddPrintTransformer und Reflexion erhalten wird der Wert angezeigt werden soll verwenden könnte. Eine Schnittstelle ist nur einfacher, wenn Sie die Quelle haben.

+0

Danke. Aber warum deklarieren Sie den 'AddPrintTransformer'-Parameter mit dem Typ' obj'? Warum nicht "ITtransformable" direkt dort verwenden? Oder verwenden Sie 'AddPrinter' sogar mit einer Funktion, die ein' ITtransformable' akzeptiert? –

+0

Es ist 'obj', weil ich zuerst die Straße der Reflexion benutzt habe. Sie können es wahrscheinlich in "ITransformable" ändern. Ich denke, 'AddPrintTransformer' ist besser für das, was Sie versuchen zu tun, da in den meisten Fällen das Delegieren auf einen anzeigbaren Wert ausreichend ist. – Daniel

Verwandte Themen