Domanda

Ho letto attraverso un buon pezzo di Expert F # e sto lavorando sulla costruzione di un effettiva applicazione. Durante il debug, mi sono abituato a passare comandi FSI come questo per rendere le cose leggibili nella finestra repl:

fsi.AddPrinter(fun (x : myType) -> myType.ToString())

desidero estendere questo per lavorare con il formattatore printf, così ho potuto tipo per esempio.

printf "%A" instanceOfMyType 

e controllare l'output per un tipo personalizzato. Il libro implica che questo può essere fatto (p 93, "formattazione strutturale generico può essere esteso per funzionare con qualsiasi tipo di dati definiti dall'utente, un argomento coperto sul sito F # "), ma non sono riusciti a trovare tutti i riferimenti su come realizzare in realtà questo. Qualcuno sa come? E 'anche possibile?

Modifica

avrei incluso un esempio di codice, si tratta di un tipo di record che ho a che fare, per esempio.

type myType = 
    {a: int}        
    override m.ToString() = "hello"

let t = {a=5}
printfn "%A" t
printfn "%A" (box t)  

entrambe le dichiarazioni di stampa Produzione:

{a = 5;}
È stato utile?

Soluzione

Sembra che il modo giusto per fare questo in F # 2.0 è quello di utilizzare la StructuredFormatDisplay attributo, per esempio:

[<StructuredFormatDisplay("hello {a}")>]
type myType = {a: int}

In questo esempio, al posto del {a = 42;} di default, si otterrebbe hello 42.

Questo funziona allo stesso modo per i tipi di oggetto, registrare, e sindacali. E anche se il modello deve essere del formato "PreText {PropertyName} PostText" ( pretesto e PostText è facoltativo), questo è in realtà più potente di ToString() perché:

  1. PropertyName può essere una proprietà di qualsiasi tipo. Se non è una stringa, allora sarà anche oggetto di formattazione strutturata. di Don Syme blog fornisce un esempio di formattazione ricorsivamente un albero in questo modo.

  2. Può essere una proprietà calcolata. Così si potrebbe effettivamente ottenere ToString() a lavorare per i tipi di record e sindacali, anche se in un modo su tutto l'piuttosto:

    [<StructuredFormatDisplay("{AsString}")>]
    type myType = 
        {a: int}
        override m.ToString() = "hello"
        member m.AsString = m.ToString()  // a property that calls a method
    

A proposito, sarà sempre utilizzato ToString() (anche per i tipi di record e sindacali) se si chiama printfn "%O" invece di printfn "%A".

Altri suggerimenti

Hmm ... Ricordo vagamente alcune modifiche a questo, ma se mi dimentico che è accaduto prima o dopo il CTP (1.9.6.2).

In ogni caso, il CTP, vedo che

type MyType() =
    override this.ToString() = "hi"
let x = new MyType()
let xs = Array.create 25 x
printfn "%A" x
printfn "%A" xs

quando valutato nella finestra VFSI fa quello che vorrei, e che

x;;
xs;;

stampa anche bene. Quindi, credo che io sono chiaro come questo si differenzia da ciò che si desidera?

In caso di superamento metodo ToString, che dovrebbe fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top