在SML中区分原子和列表

时间:2014-10-17 22:28:33

标签: programming-languages sml nested-lists smlnj ml

我是SML编程的新手,我有一个问题就是创建一个函数来从整数列表中删除原子A的出现。此列表可以嵌套到任何级别, 意味着我们可以有[1,2,3]这样的列表,我们可以有像[[1,2],[2,3]]这样的列表以及像[[[1,2],[1,2]这样的列表],[[2,3],[2,3]]]。
所以我的问题是如何检查给定的项目是列表还是原子,因为到目前为止我还没有在SMLNJ中找到任何这样的函数?
我创建了一个函数,检查列表是否为空,然后调用辅助迭代函数来检查列表的头部是列表还是原子。如果它是一个原子,那么用另一个原子替换它并继续尾部的其余部分。

如果我检查列表头部的尾部是空的,那么在辅助函数内部会出现错误,因为尾部函数只能有一个列表。
所以我必须这样做 tl([hd(a)),如果我这样做,那么它将永远是空的 如果我将它应用于第一个列表,我将其作为1并将其包含在[]结果[1]中,因此它的尾部将是[]。同样的方法,如果我得到第二个列表的头部将是[1,2]并将其包装在[]中将导致[[1,2]],所以这的尾部再次是[]。 那么我有什么方法可以检查给定的项目是原子还是列表?

提前感谢所有回复。

2 个答案:

答案 0 :(得分:2)

“此列表可以嵌套到任何级别”在SML中是不可能的,因为它是静态类型的,并且列表类型具有特定的元素类型。您有一个int list,其元素都是int,或int list list,这是一个元素都是int list的列表。你不能混合。

与您所说的最接近的是再次使用两种情况,一个叶子或此数据类型的嵌套元素列表来生成代数数据类型。然后,您可以使用模式匹配来解构此数据类型。

答案 1 :(得分:0)

如其他答案中所述:

您可以定义自己的数据类型

datatype 'a AtomList = Atom of 'a | List of 'a AtomList list

然后,使用此数据类型,您可以定义上面提到的所有原子列表:

val x = List([Atom(1),Atom(2),Atom(3)])
val y = List([List([Atom(1),Atom(2)]),List([Atom(3),Atom(4)])])
val z = List([
        List([
            List([Atom(1),Atom(2)]),
            List([Atom(1),Atom(2)]),
            List([
                List([Atom(2), Atom(3)]),
                List([Atom(2), Atom(3)])
                ])

            ])
        ])

然后要查看原子列表,您将使用模式匹配,如:

fun show xs =
    case xs of
        Atom(x) => (*do something with atom*)
      | List(ys) => (*do something with list of atoms *)