1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#light

type T = A | B | C
    with
        member this.toString() = 
            match this with
            | A -> "A"
            | B -> "B" 
            | C -> "C"
        static member fromString s =
            match s with
            | "A" -> A
            | "B" -> B 
            | "C" -> C
            | _ -> A // default

do
    System.Console.WriteLine (any_to_string <| T.fromString("B"));
    let x = A in System.Console.WriteLine (x.toString());
By on 1/10/2009 8:36 PM ()

If you want to print something in F#, use:

printf "%A\n" (T.fromString "B")
instead of System.Console.WriteLine(any_to_string ...

By on 1/10/2009 9:36 PM ()

Or better

1
printfn "%A" (T.fromString "B")
By on 1/10/2009 11:31 PM ()

Thank you guys!
-Jiri

By on 1/11/2009 2:47 AM ()

Stephan, jdh30 -
First question: which namespace should "fromString" live in?
It's not mentioned in the F# language spec, and FSI.exe doesn't understand it, either:

> type T = A | B | C;;
> printfn "%A" (T.fromString "B");;
printfn "%A" (T.fromString "B");;
----------------^^^^^^^^^^^
stdin(3,17): error FS0039: The field, constructor or member 'fromString' is not defined.

Second question: how to convert the union to string. Following Stephan's example, I tried the following:

> let myString = printfn "%A" B;;
val myString : unit
B
> myString;;
val it : unit = ()

So (if I understand correctly) my "str" variable holds a reference to a function returning "B" - how do I de-reference to get the actual string "B"?

Thanks for your patience,
Jiri

By on 1/11/2009 12:40 PM ()

Jon was replying to deexp's post. So you need to use the type definition with the static member "fromString" from deexp's post. I just wanted to point out that it's safer to use printfn "%A" instead of printf "%A\n".

Stephan

By on 1/11/2009 12:54 PM ()

So there is nothing like Enum.Parse for unions?
Is there an API for listing all members of a union (besides reflection)?

And as for converting to a string, thanks for pointing me in the right direction -
the answer is
sprintf "%A" B

Thanks again,
Jiri

By on 1/11/2009 1:56 PM ()

If it's an enum (and not a union), you may use Enum.Parse.

See [link:research.microsoft.com] for more details on the enum types.

Here is the example they use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 type Color =
 | Red = 0
 | Green = 1
 | Blue = 2

let rgb = Color.Red, Color.Green, Color.Blue

let show(colorScheme) =
   match colorScheme with
   | (Color.Red, Color.Green, Color.Blue) -> printfn "RGB in use"
   | _ -> printfn "Unknown color scheme in use"

let red : Color = enum<Color>(0)
let unknownColor : Color = enum<Color>(7)

And a test function for enum parsing :

1
2
let f s = 
  System.Enum.Parse(typeof<Color>, s)
By on 1/12/2009 6:02 AM ()

There's no equivalent of Enum.Parse because unions are considerable more complex than enums - they could have any type nested within them. Reflection is the correct way to find all the members of a union, it's the way to go for any dynamic type inspection.

Cheers,

Rob

By on 1/12/2009 4:09 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