In F# Interactive (fsi), you can use AddPrinter
or AddPrinterTransformer
to provide pretty printing for a type in the interactive session. How can I add such a printer for a generic type? Using the wildcard _
for the type doesn't work:
> fsi.AddPrinter(fun (A : MyList<_>) -> A.ToString());;
The printer just isn't used.
Putting in a type parameter also gives a warning:
> 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'.
which is not what I want, either.
This won't work for the general case, but since it appears you're working with your own type (at least in your example), and assuming you don't want to affect ToString
, you could do something like this:
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)
Output:
> MyList([1;2;3])
val it : MyList<int> = [1; 2; 3]
For a third-party generic type you could use AddPrintTransformer
and reflection to get the value to be displayed. An interface is just easier if you have the source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With