Reputation:
So I am attempting to create a list of a discriminate union type such as;
type ColType = Int of int | Float of float | String of string
And then insert into a list, such as
let addToList (list : ColType list) (col : ColType) =
let list' = list @[col]
list'
However I am unsure how to initialize the coltype values as I only get values such as int -> coltype etc.
I tried this function
let createColType x =
if x.GetType() = int then
Int x
else if x.GetType() = float then
Float x
else if x.GetType() = string then
String x
else
String x
Which obviously doesnt work as it will return different values, so how would you go about solving this?
Upvotes: 2
Views: 244
Reputation: 3183
type Food = Hamburgers of int | Soda of float | Other of string
module Food =
let tryCreate food =
match box food with
| :? int as i -> Some(Hamburgers i)
| :? float as f -> Some(Soda f)
| :? string as s -> Some(Other s)
| _ -> None
let burgers = Hamburgers 7
let soda = Soda 3.2
let mozzarellaSticks = Other "Mozzarella Sticks"
let mysteryMeat = Option.toList(Food.tryCreate "nobody knows")
let list = [burgers; soda; mozzarellaSticks] @ mysteryMeat
By using an Option
as the return type for my tryCreate
I will not get any runtime exception. You'll notice also that I've tried to create DU labels that associate with my business goals. This makes it easier to express intent, and makes the unions more useful than simple ints, strings, and floats. Most of the time I know what type I have because the type corresponds to a business use, so I don't have to write or use a tryCreate. Often in practice it's not meaningfully possible to map primitives to our discriminated unions, consider for example if we added a | Hotdogs of int
it's ambiguous if any int we add is a hotdog or a hamburger.
Upvotes: 0
Reputation: 5004
Use match
to check multiple options and :?
to match the type:
let createColType x =
match box x with
| :? int as i -> ColType.I i
| :? float as f -> ColType.F f
| :? string as s -> ColType.S s
|_-> failwithf "Type not supported %A" <| x.GetType().FullName
createColType 1 |> printfn "%A" // shows: I 1
createColType 2. |> printfn "%A" // shows: F 2.0
createColType "3" |> printfn "%A" // shows: S "3"
Upvotes: 1