标准ML中列表上的地图功能

时间:2018-03-08 21:11:46

标签: sml ml mosml

基于这个定义:

附加列表是列表抽象数据类型的(简单)实现,它使构造便宜(O(1)),但使破坏变得昂贵(O(n))。 'a alistNN'a alist类型的定义如下:

datatype 'a alistNN = Sing of 'a | Append of 'a alistNN * 'a alistNN
datatype 'a alist = Nil | NonNil of 'a alistNN

'a alistNN类型表示“非零”附加列表,而'a alist类型表示任意(零或非零)附加列表。

我要求将地图功能定义为:

fun alistMap (f: 'a -> 'b) (xs: 'a alist): 'b alist =

在追加清单上执行地图。

我将其定义如下:

fun alistMap (f: 'a -> 'b) (xs: 'a alist): 'b alist =
    case xs of
      Nil => Nil
    | NonNil xs => 
      let
        fun mapNN(f: 'a -> 'b) (xs: 'a alist): 'b alist =
           case xs of 
             Sing x => Sing (f x)
           | Append (ys, zs) => 
             let
               val ws = mapNN f ys
               val ts = mapNN f zs
             in
               alistAppend (ys , zs)
             end
      in
        mapNN f xs
      end

我不断发生冲突类型,特别是:

Sing x => Sing (f x)

知道可能导致这种情况的原因是什么?

1 个答案:

答案 0 :(得分:2)

您的内部函数mapNN使用错误的类型进行注释。构造函数SingAppend形成alistNN类型的值,而不是alist。所以它应该注释如下。

fun mapNN (f : 'a -> 'b) (xs : 'a alistNN) : 'b alistNN = ...

您的代码还有其他一些问题:

  1. alistAppend (ys, zs)行的类型为'a alist,但该函数需要返回'b alistNN类型的内容,因此这将是类型错误。作为解决此问题的提示,请注意您创建了值wsts,但从未使用过它们......;)

  2. 修复mapNN后,行mapNN f xs上会出现类型错误,因为它的类型为'b alistNN,但需要类型{{1} }}

  3. 总之,请注意'b alistalist之间的区别。这是两种不同的类型,具有不同的构造函数,并且具有根本不同的含义!