Functional programming 如何从数据类型中提取元组?
熟悉SML,并尝试通过一系列练习进行学习。我试图写的函数是关于用N个孩子压平一棵树。我的方法是简单地获取当前的Functional programming 如何从数据类型中提取元组?,functional-programming,sml,Functional Programming,Sml,熟悉SML,并尝试通过一系列练习进行学习。我试图写的函数是关于用N个孩子压平一棵树。我的方法是简单地获取当前的NTreeNode,并将其值添加到我将返回的某个列表中。然后接受它的第二个参数,孩子的列表,并将其附加到另一个列表上,这将是我的队列。这个队列将作为我仍然要处理的所有项目 我试图通过将NTreeList和我将返回的列表以及flattentree中的初始值传递给一个helper函数来实现这种方法 但是,当我试图处理队列中的NTreeNode时,它会返回一个NTree,并且我不能对其使用第一
NTreeNode
,并将其值添加到我将返回的某个列表中。然后接受它的第二个参数,孩子的列表,并将其附加到另一个列表上,这将是我的队列。这个队列将作为我仍然要处理的所有项目
我试图通过将NTreeList
和我将返回的列表以及flattentree
中的初始值传递给一个helper函数来实现这种方法
但是,当我试图处理队列中的NTreeNode
时,它会返回一个NTree
,并且我不能对其使用第一个
/第二个
函数,我需要从队列中返回一个元组。我只是不知道如何取回元组,我尝试使用NTreeNode
构造函数,但即使这样,我也会得到一个NTree
我的问题是如何从我定义的NTree
数据类型中提取元组
datatype NTree =
NTreeNode of int * NTree list
| EmptyNTree
;
fun first (a, _) = a;
fun second (_, b) = b;
fun processTree queue finalList =
if null queue
then finalList
else processTree ((tl queue)@(second(NTreeNode(hd queue)))) finalList@[first (NTreeNode (hd queue)) ]
;
fun flattenNTree EmptyNTree = []
| flattenNTree (NTreeNode x) = processTree (second x) [(first x)]
;
输入值示例:
val t =
NTreeNode (1, [
NTreeNode (2, [
NTreeNode (3, [EmptyNTree]),
NTreeNode (4, []),
NTreeNode (5, [EmptyNTree]),
EmptyNTree
]),
NTreeNode (6, [
NTreeNode (7, [EmptyNTree])
])
]);
您的
processTree
函数缺少EmptyNTree
的情况,您似乎试图在调用first
和second
之前添加NTree
构造函数,而您需要像在flattentree
中那样将它们去掉
这两个问题都可以通过对队列头应用模式匹配来解决:
fun processTree queue finalList =
if null queue
then finalList
else case hd queue of
EmptyNTree => processTree (tl queue) finalList
| NTreeNode v => processTree (tl queue @ second v) (finalList @ [first v])
;
您也可以考虑基于列表函数的实现(虽然结果的顺序不一样):
使用模式匹配来分解东西要比摆弄诸如
first
或tl
之类的选择器容易得多
相反地累积一个列表并在完成时修复它也比重复地追加到列表末尾更有效
fun processTree [] final = reverse final
| processTree (EmptyTree::ts) final = processTree ts final
| processTree ((NTreeNode (v,t))::ts) final = processTree (ts @ t) (v :: final)
给定树类型
datatype 'a tree = Node of 'a * 'a tree list
| Leaf
您可以将其折叠:
fun fold f e0 Leaf = e0
| fold f e0 (Node (x, ts)) =
let val e1 = f (x, e0)
in foldl (fn (t, e2) => fold f e2 t) e1 ts
end
并将其展平:
fun flatten t =
fold op:: [] t
fun flatten t =
fold op:: [] t