Do you need an interface for this? You already have a source type defined by a JSON type provider. Why not define a specific type of destination?
. - , . , , OOD, .
, , , :
type Graph<'a> = { Node : 'a; Children : Graph<'a> list }
, SalesComponentJson JSON, , , JSON :
let createHierarchies (xs : SalesComponentJson.Root list) =
let rec findChildren parentId =
xs
|> List.filter (fun x -> x.ParentId = Some parentId)
|> List.map (fun x -> { Node = x.Name; Children = findChildren x.Id })
xs
|> List.filter (fun x -> x.ParentId.IsNone)
|> List.map (fun root -> { Node = root.Name; Children = findChildren root.Id })
, - JSON . , , , .
:
let salesComponents = [
SalesComponentJson.Parse """{ "ID":0, "name":"All Media" }"""
SalesComponentJson.Parse """{ "ID":1, "parentID":0, "name":"Foo" }"""
SalesComponentJson.Parse """{ "ID":2, "parentID":1, "name":"Bar" }"""
SalesComponentJson.Parse """{ "ID":3, "parentID":1, "name":"Baz" }"""
SalesComponentJson.Parse """{ "ID":4, "parentID":0, "name":"Qux" }"""
SalesComponentJson.Parse """{ "ID":5, "parentID":4, "name":"Corge" }""" ]
FSI:
> createHierarchies salesComponents;;
val it : Graph<string> list =
[{Node = "All Media";
Children =
[{Node = "Foo";
Children = [{Node = "Bar";
Children = [];}; {Node = "Baz";
Children = [];}];};
{Node = "Qux";
Children = [{Node = "Corge";
Children = [];}];}];}]
.