我编写了一个有序的树遍历函数:
let rec inOrder (tree: BinTree<'a>) : 'a list =
match tree with
| Leaf -> []
| Node(x,l,r) -> (inOrder l) @ [x] @ (inOrder r)
现在,我想使用此功能来“映射”所有音符并应用作为参数给出的功能。它应该带有一个函数和一棵树,然后返回一棵树。这是我到目前为止的内容:
let mapInOrder f t =
inOrder t
|> Map.ofList
例如,如果我为函数提供以下输入:
mapInOrder float (Node(1,Node(2,Leaf,Leaf),Node(3,Leaf,Leaf)));;
我想要输出:
(Node(1.0,Node(2.0,Leaf,Leaf),Node(3.0,Leaf,Leaf)))
答案 0 :(得分:4)
要在List
上映射函数,请使用函数List.map
:
let mapInOrder f t =
inOrder t
|> List.map f
但是此函数将产生一个List作为输出。您的示例将产生:
[ 1.0 ; 2.0 ; 3.0 ]
要产生输出,您希望mapInOrder
应该遍历该树,然后将该函数应用于每个元素。
答案 1 :(得分:1)
这是我随附的:
type BinTree<'a> =
| Leaf
| Node of x :'a * l:BinTree<'a> * r:BinTree<'a>
let rec inOrder (tree: BinTree<'a>) : 'a list =
match tree with
| Leaf -> []
| Node(x,l,r) -> (inOrder l) @ [x] @ (inOrder r)
let exampleTree = (Node(1,Node(2,Leaf,Leaf),Node(3,Leaf,Leaf)));;
let mapInOrder tree mapFunc =
tree
|> inOrder
|> List.map mapFunc
let res = mapInOrder exampleTree double
//val res : double list = [2.0; 1.0; 3.0] <-------------- result of your current try
let rec copyAndMapInOrder<'b> (tree: BinTree<'a>) mapFunc : BinTree<'b> =
match tree with
| Leaf -> Leaf
| Node(x,l,r) -> Node((mapFunc x), (copyAndMapInOrder l mapFunc), (copyAndMapInOrder r mapFunc))
let res2 = copyAndMapInOrder exampleTree double
//val res2 : BinTree<double> = Node (1.0,Node (2.0,Leaf,Leaf),Node (3.0,Leaf,Leaf)) <-- expected result
这段代码只是我对@AMieres上面建议的实现。
答案 2 :(得分:0)
添加到其他答案中的一件简单的事情。您可以定义折叠函数并从中导出其他函数。
let rec fold (e: 'b) (f : 'a -> 'b -> 'b -> 'b) (tree: BinTree<'a>) : 'b =
match tree with
| Leaf -> e
| Node(x,l,r) -> f x (fold e f l) (fold e f r)
let inorderTree f t = fold Leaf (fun x l r -> Node (f x, l, r)) t
let inorderList f t = fold [] (fun x l r -> l @ [f x] @ r) t
let inorderList' t = inorderList id t
let inorderTree' t = inorderTree id t