我正在尝试使用两个值构造函数定义一个新的多态类型generic_list
:List
和Seq
,并添加映射map_function (proc, items)
的函数proc
超过所有项目。
这是我到目前为止所做的:
datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);
datatype 'a generic_list = List of 'a list | Seq of 'a seq;
如何构建map_function
当我有以下要求时:
generic_map (proc, items)
map
相同,但项目可以是常规列表或惰性列表。fn: ('a -> 'b) * 'a generic_list -> 'b generic_list
示例:
generic_map (fn x => x + 10, List [1, 2, 3]);
val it = List [12,13,14]: int generic_list
generic_map (fn x => x + 10, Seq (Cons (1, fn () => Cons(2, fn () => Cons (3, fn () => Nil)))));
val it = Seq (Cons (11, fn)): int generic_list
答案 0 :(得分:1)
我猜测 map
在课堂中定义你的意思是来自Standard ML Basis Library的列表的map
函数?无论如何,你有一个带有两个构造函数的数据类型,一个用于List
s,一个用于Seq
s,因此在顶层,你的函数应该区分这两种情况,即
fun generic_map (f, List xs) = List (...) (*map f over xs*)
| generic_map (f, Seq s) = Seq (...) (*map f over s*)
对于第一种情况,您可以使用List.map
几乎免费获得所需内容。唯一剩下的就是为惰性列表定义一个map-function。它的形状将是这样的:
fun map_seq (f, Nil) = ... (*map f over the empty sequence*)
| map_seq (f, Cons (x, s)) = ... (*map f over x and the remaining sequence s*)
备注:由于它是您的规范的一部分,您可能不被允许更改它 - 也许这更符合品味 - 但我发现您的类型为懒惰列表a有点奇怪,因为在你的情况下,懒惰列表的尾部与懒惰列表的类型不同(即,列表的头部不会被懒惰地访问)。在类似的情况下,我宁愿使用
datatype 'a cell = Nil | Cons of 'a * (unit -> 'a cell);
type 'a seq = (unit -> 'a cell);
或
datatype 'a seq = Seq of unit -> ('a * 'a seq) option;
其中空序列由Seq (fn () => NONE)
编码。