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.