木が立ち往生しているので脳が痛いとき、私は自分が欲しいものをできるだけ簡単かつ明確に言おうとします。
- 情報のツリーが与えられたら、述語に一致するすべてのサブツリーをリストします(この場合、info = 3)。
これを行う簡単な方法の1つは、ツリーのすべてのノードをリストしてから、述語でフィルター処理することです。
type 'info tree = Node of 'info * 'info tree list
let rec visit = function
| Node( info, [] ) as node -> [ node ]
| Node( info, children ) as node -> node :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter (fun (Node(info,_)) -> predicate info)
OPのサンプルデータに対して実行されたツリーフィルターは次のとおりです。
let result = filter (fun info -> info = 3) test
私を驚かせたのは、適切な述語を持つ任意の情報タイプに対してコードがいかに簡単に機能するかということです。
let test2 =
Node(("One",
[Node("Two",
[Node("Three",[Node("Five",[]);Node("Three",[])]);
Node("Three",[])]);
Node("Three",[])]))
let res2 = filter (fun info -> info = "Three") test2
または、サブツリーではなく情報を一覧表示する場合、コードは驚くほど単純です。
let rec visit = function
| Node( info, [] ) -> [ info ]
| Node( info, children ) -> info :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter predicate
これは同じクエリをサポートしますが、ツリー構造ではなく、'infoレコードのみを返します。
let result = filter (fun info -> info = 3) test
> val result : int list = [3; 3; 3; 3]