SML使用带签名的abstype

zlo*_*leo 4 functional-programming sml abstract-data-type functor

我正在编写一个库来处理Standard ML中的简单图像.它应该支持用作每个像素的颜色的不同类型,例如bool,Word8.word等.

我有一个abstype 'a image所有常见的函数定义独立于表示('a是颜色表示),但输出格式不同,所以我想有不同的结构.

有没有办法"打开" abstype一个结构内部?我只能以非常丑陋的方式工作:

abstype 'clr absimage = Image of {width : int, height : int, data : 'clr array array}
with
    fun createFunc (w, h) f = Image {width = w, height = h, data = ...}
    fun createBlank (w, h) clr = createFunc (w, h) (fn _ => clr)
    ...
end
signature IMAGE = sig
    type colour
    type image
    val createFunc : (int * int) -> (int * int -> colour) -> image
    val createBlank : (int * int) -> colour -> image
    ...
    val toBinPPM : image -> string -> unit
end
functor ImageFn(C : sig type colour end) = struct
    open C
    type image = colour absimage
    val createFunc = createFunc
    val createBlank = createBlank   
    ...
end
structure Image8 :> IMAGE = struct
    structure T = ImageFn(struct type colour = Word8.word end)
    open T

    fun toBinPPM img filename = ...
end
Run Code Online (Sandbox Code Playgroud)

特别是,仿函数的定义需要编写类似于部分中val name = name定义的所有函数的语句.with ... endabstype

或者我的做法完全错了?

这种组合abstypesignature我尝试使用常用方法重新创建OOP的抽象类,abstype并要求在所有结构中使用其他方法实现signature

PS为什么SML不允许语句open (ImageFn(struct ... end))和强制使用临时结构(T在上面的代码中)?

And*_*erg 5

没有理由abstype在今天的SML中使用.考虑它已被弃用.它是模块前时代的遗留物.您可以实现隐藏具有结构,签名和密封(:>操作符)的类型的构造函数的相同效果,但是以更灵活和一致的方式.这也解释了为什么它没有很好地与模块集成 - 它早于它们并且基本上被它们取代.

在您的具体实例,而不是使用abstype,简单地定义imagedatatype在体内直接ImageFn仿函数,并隐藏它的构造与签名注释,如下所示:

signature IMAGE =
sig
  type colour
  type image
  val createFunc : int * int -> (int * int -> colour) -> image
  val createBlank : int * int -> colour -> image
  ...
end

signature IMAGE8 =
sig
  include IMAGE
  val toBinPPM : image -> string -> unit
end

functor ImageFn(type colour) :> IMAGE =
struct
  datatype image = Image of {width : int, height : int, data : colour array array}
  fun createFunc (w, h) f = Image {width = w, height = h, data = ...}
  fun createBlank (w, h) clr = createFunc (w, h) (fn _ => clr)
  ...
end

structure Image8 :> IMAGE8 =
struct
  structure T = ImageFn(type colour = Word8.word)
  open T
  fun toBinPPM img filename = ...
end
Run Code Online (Sandbox Code Playgroud)

编辑:事实上,在这种情况下甚至不需要定义image为数据类型.普通类型也可以做,并使代码稍微简单:

type image = {width : int, height : int, data : colour array array}
Run Code Online (Sandbox Code Playgroud)

至于你的PS问题:是的,我也不知道.没有特别的原因.一些SML方言将其实现为扩展.