#f#
#f#
Вопрос:
Я умудрился приготовить себе огромную миску спагетти и не могу найти выход. Я пытаюсь вставить тип в дерево и впоследствии изменить порядок расположения следующих деревьев.
Вот мои типы:
type Government = {
Id : Id;
Name : string;
Abbreviation : string;
ParentId : string option;
}
type GovernmentStructure<'gov> =
| Root of Government : 'gov * SubGov : GovernmentStructure<'gov> list
| Node of Government : 'gov * SubGov : GovernmentStructure<'gov> list
| Leaf of Government : 'gov
а вот и спагетти, лол. Это не работает, но это показывает мозговой штурм, в который я попал.
let insertGovernment (posGov: Government) (newGov : Government) (parentId : string)
(currentStructure : GovernmentStructure<Government> list) =
let rec reorderStructure (govPos : Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
match currentStructure with
| Root(gov', subGov) when gov' = govPos ->
let rec updateSubGov parentId (movGov: Government)
(uSubGov : GovernmentStructure<Government> list) =
[
Node({
Government.Id = movGov.Id;
Name = movGov.Name;
Abbreviation = movGov.Abbreviation;
ParentId = Some(parentId)
},[
for x in uSubGov do
match x with
| Node(g, s) -> yield! (updateSubGov movGov.Id g s)
| Leaf(g) -> yield x
])
]
Root(newGov, (updateSubGov newGov.Id gov' subGov))
| node ->
let rec updateStructure parentId (insGov : Government)
(node : GovernmentStructure<Government> list) =
match node with
| Root(gov', subGov) ->
Root(gov', [
for (x) in subGov do
match x with
| Node(g,s) when g = govPos ->
yield Node(insGov, updateStructure g.Id s )
| Node(g,s) -> yield Node(g, updateStructure g.Id s)
])
| Node(gov', subGov) when gov' = govPos ->
[
Node({
Government.Id = insGov.Id;
Name = insGov.Name;
Abbreviation = insGov.Abbreviation;
ParentId = Some(parentId)
},[
for x in uSubGov do
match x with
| Node(g,s) -> yield Node(g, updateStructure movGov.Id g s)
])
]
| Leaf(g) ->
[
Node(newGov, [Leaf({
g with ParentId = newGov.Id
})])
]
node |> (fun x ->
match x with
| Root(g,s) -> Node(g,(updateStructure g.Id g s))
| Node(g,s) -> Node(g,(updateStructure g.Id g s)))
Помогите!!! Я тону в соусе, лол.
Комментарии:
1. Быть более конкретным, чем не сработало
2. Не знаю, что вы подразумеваете под «не работает», но я заметил, что в вашем
match
выражении вupdateStructure
есть несоответствие типов. ВашRoot
регистр возвращает одинGovernmentStructure
элемент (в частности,Root
), но вашиNode
иLeaf
регистры возвращают списокGovernmentStructure
элементов. В обоих случаях в этом списке есть только один элемент, так что вы могли бы изменить регистр, чтобы возвращать толькоNode
вместо списка, и тогдаmatch
все совпадало бы (хех).3. Также
updateStructure
говорится, чтоnode
параметром являетсяGovernmentStructure list
, но вы сопоставляете его с отдельнымиGovernmentStructure
случаями. Это еще одно несоответствие типов.
Ответ №1:
Это решение, которое я смог придумать. Я бы не сомневался, что существует более эффективный ответ.
let insertGovernment (posGov: Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
let updateStructure (govPos : Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
// iterate over the nodes to find position and insert. parentId is useless, will fix later
let rec findPosAndInsertInto parentId (startStructure : GovernmentStructure<Government>) =
match startStructure with
| Node (g, sg) when g = govPos ->
Node(g, [
yield Node(newGov, [])
yield! sg
])
| Node (g, sg) ->
Node (g, [
for x in sg do
yield findPosAndInsertInto g.Id x
])
| Leaf(g) when g = govPos ->
Node (g, [Leaf(newGov)])
// better logic needed, should not hit this
| node -> node
match currentStructure with
// Insert if position is at root
| Root(gov', subGov) when gov' = govPos ->
Root(gov', [
yield Node(newGov, [])
yield! subGov
])
// Insert if position is at node or leaf
| node ->
match node with
| Root (gov', subGov) ->
Root(gov', [
for x in subGov do
yield findPosAndInsertInto gov'.Id x
])
// better logic needed, shouldn't hit this level
| node -> node
updateStructure posGov newGov currentStructure