This is done with the

1
Reflection.FSharpValue

class. Example code:

1
2
3
4
5
6
7
8
9
type Tile =
| S1 of int
| H2 of int
| V2 of int
| S2 of int
  with override t.ToString() =
    let (uci, [|i|]) = Reflection.FSharpValue.GetUnionFields(t, typeof<Tile>)
    let i = i :?> int
    System.String.Format("{0}({1})", uci.Name, i*i)
By on 3/3/2010 8:15 AM ()

Ha! Now we're talking! Thanks a lot!

By on 3/3/2010 8:34 AM ()

Note that using reflection is unsafe - if some day you edit your type, you might get a runtime exception. Alternatively, writing a type-checked accessor is not that long:

let get = function S1 i | H2 i | V2 i | S2 i -> i
or
let get (S1 i | H2 i | V2 i | S2 i) = i

Laurent.

By on 3/5/2010 8:59 AM ()

After looking at the implementation of DUs (with cases as subclasses etc) and from the fact that print_any uses reflection, i'm guessing there's no other way than reflection...

Edited to add:
Using the name of the type does the trick:

1
2
3
4
5
6
7
type Tile =
    | S1 of int
    | H2 of int
    | V2 of int
    | S2 of int
    with override t.ToString() =
           String.Format("{0}({1})", t.GetType().Name, "something")

But of course there is no easy way of extracting the 'item' value, since S1, H2 etc are different types.

Feature request: It would be cool if the compiler recognised that all cases encapsulate the same type (int) and generated a property accessible from all Tile types.

Sorry if all this had been posted before.

By on 3/3/2010 6:34 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper