3

I was wondering if there is a simple way to add pretty printing to a custom type used in a Deedle data frame.

In the following example:

open Deedle

type PrimaryContactInfo =
    | Default of int
    | NonDefault of int
    | Missing

type Account = { PrimaryContact : PrimaryContactInfo }

[ { PrimaryContact = Default(1) }; { PrimaryContact = Default(2) }; { PrimaryContact = NonDefault(5) } ]
|> Frame.ofRecords

I get the following output in fsi:

     PrimaryContact                         
0 -> FSI_0011+PrimaryContactInfo+Default    
1 -> FSI_0011+PrimaryContactInfo+Default    
2 -> FSI_0011+PrimaryContactInfo+NonDefault 

but I would rather have output like this:

     PrimaryContact                         
0 -> Default(1)    
1 -> Default(2)   
2 -> NonDefault(5)

Is this possible?

jeremyh
  • 612
  • 4
  • 14

1 Answers1

4

As implied by this language feature suggestion, F# discriminated unions don't automatically convert nicely to strings.

You can make it convert nicely by overriding ToString:

type PrimaryContactInfo =
    | Default of int
    | NonDefault of int
    | Missing
    override this.ToString () = sprintf "%A" this

Notice, however, that the use of "%A" may be slow, so measure, and write a faster, more explicit implementation if necessary; for example:

type PrimaryContactInfo =
    | Default of int
    | NonDefault of int
    | Missing
    override this.ToString () =
        match this with
        | Default i -> sprintf "Default %i" i
        | NonDefault i -> sprintf "NonDefault %i" i
        | Missing -> "Missing"

This produces exactly the same output as sprintf "%A, but doesn't use Reflection, so should, in theory, be faster (but don't take my word on it: measure).

Jakub Lortz
  • 14,616
  • 3
  • 25
  • 39
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736