我正在尝试在sml中编写一个函数,它“解包”任意深度的嵌套列表。例如,unpack [[[1,2]]]应该产生[1,2]。我正在尝试类似的事情:
有趣解包xs = if nestedp(xs)然后解压(hd xs)其他xs;
与 有趣的nestedp [_] =真 | nestedp _ = false;
sml不喜欢以这种方式定义unpack,因为它将unpack的类型推断为'a list - > '一个 。对hd的调用的返回被传递回unpack,但它现在不会“看到”列表而是单个变量。
是否有可能以这种方式解压缩嵌套列表?
答案 0 :(得分:1)
您不能对内置列表类型执行此操作,因为您无法使类型匹配。
例如,有人可能认为使用类型'a list list -> 'a list
的函数是可能的,然后递归地应用它,直到它到达非嵌套列表的基本情况。但是,您无法以任何方式检测基本情况,从而使您的类型不匹配。
但是,如果您创建了自己的列表类型,则可以这样做:
datatype 'a nestableList = Cons of 'a * 'a nestableList
| NCons of 'a nestableList * 'a nestableList
| Nil;
此处,Cons
和Nil
与::
和[]
的工作方式相同,而NCons
则允许嵌套列表构建。
举个例子:
(* The list [[1, 2], [[3], [4, 5, 6]]] *)
val nlist = NCons(
Cons(1, Cons(2, Nil)),
NCons(
NCons(
Cons(3, Nil),
Cons(4, Cons(5, Cons(6, Nil)))
),
Nil
)
);
然后你可以像这样展平这个嵌套列表类型:
fun flatten nls =
let
fun flatten_ Nil = []
| flatten_ (NCons(head, tail)) = flatten head @ flatten tail
| flatten_ ( Cons(head, tail)) = head :: flatten tail
in
flatten_ nls
end;
然后可以像这样使用
val flattenedNlist = flatten nlist; (* Yields [1, 2, 3, 4, 5, 6] *)
这里我得到了一个常规列表,但可以很容易地改变它来返回相同类型的列表。