typescastingf#primitive

F# cast / convert custom type to primitive


I've designed my app domain with custom F# types, but now it seems like these custom types will be a PITA when I want to actually use the data for various tasks... i.e. writing values to a CSV file, using other libraries that rely on primitives, etc.

For example, I have a custom type like this (which is used as a building block for other larger types):

type CT32 = CT32 of float

But code like this doesn't work:

let x = CT32(1.2)
let y = float x //error: The type "CT32" does not support a conversion...
let z = x.ToString() //writes out the namespace, not the value (1.2)

I've tried to use box/unbox and Convert.ToString() and the two F# casting operators but none of them seem to allow me to access the base primitive value contained by my types. Is there an easy way to get to the primitive values in custom types because so far they've been more of a headache than actually useful.


Solution

  • Your type CT32 is a Discriminated union with one case identifier CT32 of float. It's not an alias to float type so you couldn't just cast it to float. To extract the value from it you can use pattern matching (this is the easiest way).

    type CT32 = CT32 of float
    let x = CT32(1.2)
    
    let CT32toFloat = function CT32 x -> x
    let y = CT32toFloat x
    let z = y.ToString()
    

    As an alternative (if your custom types are numeric) you can use Units of Measure https://msdn.microsoft.com/en-us/library/dd233243.aspx They don't have runtime overhead (I believe discriminated unions are compiled to classes) but provide type safety at compile time.