functional-programming - 如何从数据类型中提取元组?

标签 functional-programming sml

SML 新手,正在尝试通过一系列练习来学习。我正在尝试编写的函数涉及展平具有 N 个子节点的树。我的方法是简单地获取当前的 NTreeNode 并将其值添加到我将返回的某个列表中。然后获取它的第二个参数,即子列表,并将其附加到另一个列表,这将是我的队列。该队列将作为我仍然需要处理的所有项目。

我尝试通过将 NTreeList 和我将使用 flattenNTree 中的初始值返回的列表传递给辅助函数来实现此方法。

但是,当我尝试处理队列中的 NTreeNode 时,它会返回一个 NTree 并且我无法使用我的 first/second 函数,我需要从队列返回一个元组。我只是不明白如何取回元组,我尝试使用 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])
    ])
  ]);

最佳答案

使用模式匹配来分解事物比摆弄诸如 firsttl 这样的选择器要容易得多。

反向累积列表并在完成后修复该列表比重复追加到列表末尾更有效。

fun processTree [] final = reverse final
  | processTree (EmptyTree::ts) final = processTree ts final
  | processTree ((NTreeNode (v,t))::ts) final = processTree (ts @ t) (v :: final)

关于functional-programming - 如何从数据类型中提取元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52674798/

相关文章:

programming-languages - 寻找函数式语言

scala - `EitherT` 不应该是协变的吗?尤其是左派?

compiler-construction - 在 "Real-World"应用程序中使用 ML

pattern-matching - SML 如何定义正确的选项

SML 列表求和

java - 使用传入的方法实例化 Java 对象

haskell - 使用无点表示法定义 `id` 函数

python - 如何处理管道中处理相互依赖的文件

sml - 替换列表中的元组

SML 列表相等奇数