Casting discriminated union without common ancestor
12:11 07 Jul 2015

I have a discriminated union:

type Attribute =
    | A of o : A
    | B of o : B
    | None

I have a function which returns a list of Attributes (Attribute list).

let attributes = foo some another

I need a create function which gets a list of Attributes and returns Result type where:

type Result =
{
    a : A[]
    b : B[]
}

The function must get each element of list and add it to corresponding array of Result type.

Here is my attempt:

let justDoIt (attributes : Attribute list) : Result = 

   let result =  { 
                    a = Array.empty;  
                    b = Array.empty 
                  }

    let accumulate (a : Attribute) (accum : Result) : Result =
        match a with
        | A o -> o :?> A |> Array.append accum.a                         
        accum

    let rec foo (attributes : Attribute list) (accum : Result) : Result =
        match attributes with
        | [] -> accum
        | hd::tail -> foo tail (accumulate hd accum)             
    
    foo attributes result

I have the problem in the accumulate function when I am tying to cast discriminated union to specific type.

Is there a way to it or it will be better to solve this task with different approach?

Updated:

type A = 
 {
    Some : int
 }

type B = 
 {
    Another : string
 }
f#