FSharpでは、次のことを行いたいと思います
与えられたタイプ: type FsTree = Node of (string * FsTree) list
述語toStringListを定義して、:toStringList myFsTree
が次の結果を与えるようにします。
結果:
[
["n1"];
["n2"; "sub_n2_1"];
["n2"; "sub_n2_2"];
["n3"; "sub_n3"; "sub_sub_n3_1"];
["n3"; "sub_n3"; "sub_sub_n3_2"];
["n3"; "sub_n3"; "sub_sub_n3_3"];
["n4"];
]
どこ
let myFsT = Node [
("n1", Node []);
("n2", Node [
("sub_n2_1", Node []);
("sub_n2_2", Node [])
]);
("n3", Node [
("sub_n3", Node [
("sub_sub_n3_1", Node []);
("sub_sub_n3_2", Node []);
("sub_sub_n3_3", Node []);
])
]);
("n4", Node [])
]
私がこれまでに行ったこと(ここでは以下)は絶対に正しくありません、私はそれを知っています。しかし、私は本当にここで立ち往生しています!誰かが何をすべきか考えていますか?
let rec test (fst:FsTree) =
match fst with
| Node [] -> []
| Node ((str, subFst)::restNode) ->
[[str] @ (test subFst)] @ (test restNode)
これは、Node
内のリスト用と内のリスト用の2つの相互再帰関数を必要とするため、注意が必要Node
です。
let rec processNode prepend node =
let rec processList prepend listOfNodes =
match listOfNodes with
| [] -> []
| (str, subNode) :: restList ->
let restList = processList prepend restList
let newPrepend = List.append prepend [ str ]
match processNode newPrepend subNode with
| [] -> [ newPrepend ]
| lst -> lst
@ restList
match node with Node listOfNodes -> processList prepend listOfNodes
processNode [] myFsT
|> List.iter print
リスト内の要素を調べるには、1つの再帰関数が必要です。 processList
もう1つは、リスト内のサブノードを調べますprocessNode
。
混乱が生じるのprocessNode
は、リストを取得してからNode
呼び出すだけなprocessList
ので、1つの関数であるかのように簡単に考えることができます。
OTOHprocessList
は二重再帰法です。リストの要素を調べるために自分自身を呼び出しprocessNode
、サブツリーをさらに深く調べるために呼び出します。
prepend
パスを運ぶアキュムレータパラメータも渡す必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加