I'm writing a library to handle simple images in Standard ML. It should support different types used as colour for each pixel, e.g. bool, Word8.word, etc.
I've got a abstype 'a image with all common functions defined independent of representation ('a is the colour representation) , but the output formats differ, so I'd like to have different structures.
Is there a way to "open" an abstype inside a structure? I can only get this working in a very ugly way:
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
In particular, the definition of the functor requires to write statements like val name = name for all functions defined in the with ... end part of abstype.
Or is my approach completely wrong?
This combination of abstype and signature is my attempt to recreate OOP's abstract class with common methods from abstype and require implementation of other methods in all structures using the signature
P.S. Why does SML disallow statements like open (ImageFn(struct ... end)) and forces to use a temporary structure (T in the above code)?