Pertanyaan Bagaimana cara menambahkan printer cantik untuk tipe generik ke fsi?


Dalam F # Interactive (fsi), Anda dapat menggunakan AddPrinter atau AddPrinterTransformer untuk menyediakan pencetakan yang cantik untuk tipe dalam sesi interaktif. Bagaimana saya bisa menambahkan printer semacam itu untuk tipe generik? Menggunakan wildcard _ karena tipenya tidak berfungsi:

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

Printer tidak digunakan.

Menempatkan dalam parameter tipe juga memberikan peringatan:

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

yang juga bukan yang saya inginkan.


6
2018-02-21 21:45


asal


Jawaban:


Ini tidak akan berfungsi untuk kasus umum, tetapi karena tampaknya Anda bekerja dengan jenis Anda sendiri (setidaknya dalam contoh Anda), dan dengan asumsi Anda tidak ingin mempengaruhi ToString, Anda dapat melakukan sesuatu seperti ini:

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)

Keluaran:

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

Untuk tipe generik pihak ketiga yang dapat Anda gunakan AddPrintTransformer dan refleksi untuk mendapatkan nilai yang akan ditampilkan. Antarmuka hanya lebih mudah jika Anda memiliki sumbernya.


7
2018-02-21 22:22