38

Expert F#のかなりの部分を読み、実際のアプリケーションの構築に取り組んでいます。デバッグ中に、repl ウィンドウで読みやすくするために、次のような fsi コマンドを渡すことに慣れてきました。

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

これを拡張してprintfフォーマッターで動作するようにしたいので、次のように入力できます

printf "%A" instanceOfMyType 

カスタムタイプの出力を制御します。この本は、これが可能であることを暗示しています (p 93、「一般的な構造フォーマットは、F# の Web サイトで取り上げられているトピックである、ユーザー定義のデータ型で動作するように拡張できます」)。実際にこれを達成するために。誰も方法を知っていますか?それは可能ですか?

編集:

コードサンプルを含める必要がありました。これは、私が扱っているレコードタイプです。

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

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

どちらの print ステートメントも次のようになります。

{a = 5;}
4

3 に答える 3

48

F#2.0でこれを行う正しい方法は、次のようにStructuredFormatDisplay属性を使用することです。

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

この例では、デフォルトの代わりに、{a = 42;}を取得しhello 42ます。

これは、オブジェクト、レコード、および共用体の型に対して同じように機能します。また、パターンは形式"PreText {PropertyName} PostText"PreTextPostTextToString()はオプション)である必要がありますが、これは実際には次の理由よりも強力です。

  1. PropertyName任意のタイプのプロパティにすることができます。文字列でない場合は、構造化されたフォーマットの対象にもなります。Don Symeのブログには、この方法でツリーを再帰的にフォーマットする例が示されています。

  2. 計算されたプロパティである可能性があります。したがって、実際には、レコードと共用体のタイプで作業を開始できますがToString()、かなり回りくどい方法です。

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

ちなみに、の代わりにToString()呼び出すと、常に(レコードおよび共用体タイプの場合でも)使用されます。printfn "%O"printfn "%A"

于 2012-11-23T23:51:44.953 に答える
4

うーん...これに対するいくつかの変更を漠然と覚えていますが、それらがCTP(1.9.6.2)の前または後に起こったかどうかは忘れています。

いずれにせよ、CTPでは、

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

VFSIウィンドウで評価すると、私が望むことを行います。

x;;
xs;;

もきれいに印刷されます。それで、これが望ましいものとどのように異なるのか、私は不明だと思いますか?

于 2009-04-26T23:00:49.570 に答える
-2

ToString メソッドをオーバーライドする場合は、それで十分です。

于 2009-04-26T23:01:41.237 に答える