F#: Error when trying to copy and update record through interface

Viewed 129

I am trying to make a function that turns any flat seq<IHierarchy> into a hierarchy. Essentially, anything that has a parentID and a seq of children should be able to be made into a hierarchy. Instead of making Hierarchy a base class with parentID and children properties [we can't as records are sealed classes] I was wondering if it was possible to make it an IHierarchy with two abstract fields that we implement for each class (parentID and children).

I attached the code below including a makeHierarchy function that tries to turn a flat seq<IHierarchy> into a hierarchy structure of IHierarchies. However, when I try using the record copy and update syntax (ie: {node with children = ...}) I am getting an error saying "The type IHierarchy does not contain a field children". I am a bit confused how to get the record {with} syntax to work for this type in the interface. Is it not possible to? Any help would be appreciated as I'm pretty new to F#.

module Hierarchy = 
    type IHierarchy =
        abstract member parentID: Option<int> 
        abstract member children: seq<IHierarchy>

module SalesComponents = 
    open Hierarchy
    type SalesComponentJson = JsonProvider<""" [{ "ID":1, "parentID":0, "name":"All Media" }, { "ID":1, "parentID":null, "name":"All Media" }]  """, SampleIsList=true>
    type SalesComponent  = {
                            ID: int; 
                            parentID: Option<int>; 
                            children: seq<SalesComponent>; 
                            name: string
                           }
                           interface IHierarchy with
                            member x.parentID = x.parentID 
                            member x.children = x.children |> Seq.map (fun c -> c :> IHierarchy)

open Hierarchy
open SalesComponents
let main argv =   
    let makeHierarchy hierarchyRecords:seq<IHierarchy> = 
        let root = hierarchyRecords |> Seq.tryFind (fun sc -> sc.parentID.IsNone)
        let rec getHierarchy (node: IHierarchy, scs: seq<IHierarchy>) = 
            {node with children = scs |> Seq.filter (fun sc -> sc.parentID.IsSome && sc.parentID.Value = node.ID )
                                      |> Seq.map    (fun sc -> getHierarchy(sc,scs))}
        root |> Option.map (fun r -> getHierarchy(r,hierarchyRecords) )
1 Answers
Related