SML 使用带签名的 abstype
SML use abstype with signatures
我正在编写一个库来处理标准 ML 中的简单图像。它应该支持用作每个像素颜色的不同类型,例如布尔值,Word8.word,等等
我有一个abstype 'a image
,所有常用函数都定义为独立于表示('a
是颜色表示),但输出格式不同,所以我想要不同的结构.
有没有办法在结构中 "open" 一个 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
特别是,函子的定义需要为abstype
的with ... end
部分定义的所有函数编写类似val name = name
的语句。
还是我的做法完全错误?
这种 abstype
和 signature
的组合是我尝试用 abstype
中的常用方法重新创建 OOP 的抽象 class 并要求在所有结构中实现其他方法使用signature
P.S。为什么 SML 不允许像 open (ImageFn(struct ... end))
这样的语句并强制使用临时结构(上面代码中的 T
)?
没有理由在今天的 SML 中使用 abstype
。认为它已弃用。它是前模块时代的遗留物。您可以通过结构、签名和密封(:>
运算符)实现隐藏类型构造函数的相同效果,但方式更加灵活和一致。这也解释了为什么它不能很好地与模块集成——它早于它们并且基本上被它们取代了。
在您的具体示例中,不使用 abstype
,而是直接在 ImageFn
函子的主体中将 image
定义为 datatype
,并隐藏其构造函数带有签名注释,如下所示:
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
编辑:事实上,在这种情况下甚至没有必要将 image
定义为数据类型。普通类型也可以,并使代码稍微简单一些:
type image = {width : int, height : int, data : colour array array}
至于你的PS问题:是的,我也不知道。没有特别的理由。一些 SML 方言将其作为扩展来实现。
我正在编写一个库来处理标准 ML 中的简单图像。它应该支持用作每个像素颜色的不同类型,例如布尔值,Word8.word,等等
我有一个abstype 'a image
,所有常用函数都定义为独立于表示('a
是颜色表示),但输出格式不同,所以我想要不同的结构.
有没有办法在结构中 "open" 一个 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
特别是,函子的定义需要为abstype
的with ... end
部分定义的所有函数编写类似val name = name
的语句。
还是我的做法完全错误?
这种 abstype
和 signature
的组合是我尝试用 abstype
中的常用方法重新创建 OOP 的抽象 class 并要求在所有结构中实现其他方法使用signature
P.S。为什么 SML 不允许像 open (ImageFn(struct ... end))
这样的语句并强制使用临时结构(上面代码中的 T
)?
没有理由在今天的 SML 中使用 abstype
。认为它已弃用。它是前模块时代的遗留物。您可以通过结构、签名和密封(:>
运算符)实现隐藏类型构造函数的相同效果,但方式更加灵活和一致。这也解释了为什么它不能很好地与模块集成——它早于它们并且基本上被它们取代了。
在您的具体示例中,不使用 abstype
,而是直接在 ImageFn
函子的主体中将 image
定义为 datatype
,并隐藏其构造函数带有签名注释,如下所示:
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
编辑:事实上,在这种情况下甚至没有必要将 image
定义为数据类型。普通类型也可以,并使代码稍微简单一些:
type image = {width : int, height : int, data : colour array array}
至于你的PS问题:是的,我也不知道。没有特别的理由。一些 SML 方言将其作为扩展来实现。