用户定义的通用列表的映射函数

时间:2013-06-07 12:53:45

标签: sml ml

我正在尝试使用两个值构造函数定义一个新的多态类型generic_listListSeq,并添加映射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
    

1 个答案:

答案 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)编码。