我是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]],所以这的尾部再次是[]。
那么我有什么方法可以检查给定的项目是原子还是列表?
提前感谢所有回复。
答案 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 *)