7

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.

Jeffrey Sax
  • 10,253
  • 3
  • 29
  • 40

1 Answers1

8

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.

Daniel
  • 47,404
  • 11
  • 101
  • 179
  • Thanks. But why do you declare `AddPrintTransformer`'s parameter to have type `obj`? Why not use `ITransformable` directly there? Or even use `AddPrinter` with a function that takes an `ITransformable`? – Jeffrey Sax Feb 23 '13 at 14:16
  • It's `obj` because I first went down the road of using reflection. You can probably change it to `ITransformable`. I think `AddPrintTransformer` is better for what you're trying to do because, in most cases, delegating to a display-able value is sufficient. – Daniel Feb 23 '13 at 14:54