I'm learning about creating composite* types in F# and I ran into a problem. I have this type and a ToString override.
type MyType =
| Bool of bool
| Int of int
| Str of string
with override this.ToString() =
match this with
| Bool -> if this then "I'm True" else "I'm False"
| Int -> base.ToString()
| Str -> this
let c = Bool(false)
printfn "%A" c
I get an error inside the ToString override that says "This constructor is applied to 0 argument(s) but expects 1". I was pretty sure this code wouldn't compile, but it shows what I'm trying to do. When I comment out the override and run the code, c
is printed out as "val c : MyType = Bool false". When I step into that code, I see that c has a property Item
set to the boolean false
. I can't seem to access this property in the code however. Not even if I annotate c
.
How should I be overriding ToString in this situation?
* I'm pretty sure these are called composite types.
When you are using a Discriminated Union (DU) (that's the appropriate name for that type), you need to unpack the value in the match statement like this:
The
Item
property that you're seeing is an implementation detail and is not intended to be accessed from F# code. Merely usingthis
doesn't work because the DU is a wrapper around the value, sothis
refers to the wrapper, not to the contained value.