0

我正在尝试generic_list使用两个值构造函数定义一个新的多态类型:Listand 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
    
4

1 回答 1

1

我猜map在类中定义是指标准 ML 基础库map中的列表函数?无论如何,您的数据类型有两个构造函数,一个用于s,一个用于s,因此在顶层,您的函数应该区分这两种情况,即ListSeq

fun generic_map (f, List xs) = List (...) (*map f over xs*)
  | generic_map (f, Seq s)   = Seq (...) (*map f over s*)

对于第一种情况,您几乎可以通过使用List.map. 剩下的唯一事情是为惰性列表定义一个映射函数。它的形状将类似于:

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*)

备注:由于它是您的规范的一部分,因此可能不允许您更改它 - 也许这更多的是品味问题 - 但我发现您的惰性列表类型有点奇怪,因为惰性列表的尾部,在您的情况下,与惰性列表的类型不同(即,列表的头部不会被惰性访问)。在类似的情况下,我宁愿使用

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)

于 2013-06-10T01:30:01.253 回答