1

我试图为可以同时保存所有类型的链表创建一个数据类型,即 void* 元素的链表,设计是创建一个Node保存记录的数据类型包含ValueNext

到目前为止我所做的是 -

datatype 'a anything = dummy of 'a ; (* suppose to hold any type (i.e void*) *)

datatype linkedList = Node of {Value:dummy, Next:linkedList}; (* Node contain this record *)

如您所见,上述尝试并没有成功,但我相信我的想法已经足够清晰,那么这里需要进行哪些更改才能使其发挥作用?

4

2 回答 2

4

我不确定您是否被迫使用记录类型。因为否则我认为这样做更简单:

datatype 'a linkedlist = Empty | Cons of 'a * 'a linkedlist

然后你可以使用它有点像:

val jedis = Cons ("Obi-wan", Cons("Luke", Cons("Yoda", Cons("Anakin", Empty))));

我认为在这里使用记录是一个糟糕的选择。我什至想不出我怎么能用这种方法来表示一个空列表。

-编辑-

要回答您关于支持多种类型的评论:

datatype polymorphic = N of int | S of string | B of bool
Cons(S("A"), Cons(N(5), Cons(N(6), Cons(B(true), Empty))));

鉴于这种情况,您可能更喜欢 SML 列表:

S("A")::N(5)::N(6)::B(true)::[];

哪个产生列表

[S "A",N 5,N 6,B true]

也就是说,一个相同类型(即多态)的列表,但是这种类型能够通过它的多个构造函数包含不同种类的东西。

于 2013-02-25T23:05:17.387 回答
3

仅供参考,如果多态列表的类型保持开放很重要,您可以使用 SML 的内置异常类型:exn。exn 类型是开放的,可以在程序的任何地方进行扩展。

exception INT of int
exception STR of string
val xs = [STR "A", INT 5, INT 6] : exn list

您可以像往常一样有选择地对特定类型进行大小写:

val inc_ints = List.map (fn INT i => INT (i + 1) | other => other)

您可以稍后扩展该类型,而无需提及其先前的定义:

exception BOOL of bool
val ys = [STR "A", INT 5, INT 6, BOOL true] : exn list

请注意,您可以将任何异常的构造放在那里(这里是 div-by-zero 异常):

val zs = Div :: ys : exn list

也就是说,这种(ab)使用确实很少有很好的用例,并且通常使用封闭的总和类型会更好,正如 Edwin 在上面的答案中所解释的那样。

于 2013-02-26T12:01:37.497 回答