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
或者我的做法完全错了?
这种组合abstype和signature我尝试使用常用方法重新创建OOP的抽象类,abstype并要求在所有结构中使用其他方法实现signature
PS为什么SML不允许语句open (ImageFn(struct ... end))和强制使用临时结构(T在上面的代码中)?
没有理由abstype在今天的SML中使用.考虑它已被弃用.它是模块前时代的遗留物.您可以实现隐藏具有结构,签名和密封(:>操作符)的类型的构造函数的相同效果,但是以更灵活和一致的方式.这也解释了为什么它没有很好地与模块集成 - 它早于它们并且基本上被它们取代.
在您的具体实例,而不是使用abstype,简单地定义image为datatype在体内直接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方言将其实现为扩展.