Standard ML中的Functor与模块系统相关,可以基于其他结构生成结构。下面是一个生成不同类型列表组合器的functor示例,但该示例存在问题:
各种类型的列表都有其优点--例如,惰性列表可以是无限长的,而连接列表具有O(1)的连接操作符。但当所有这些列表类型都符合相同的签名时,functor只能使用它们的普遍属性。
因此,我的问题是:有什么好的例子说明functor何时有用,而生成的各种结构不会失去其特殊能力?
signature MYLIST =
sig
type 'a t
val null : 'a t -> bool
val empty : 'a t
val cons : 'a * 'a t -> 'a t
val hd : 'a t -> 'a
val tl : 'a t -> 'a t
end
structure RegularList : MYLIST =
struct
type 'a t = 'a list
val null = List.null
val empty = []
val cons = op::
val hd = List.hd
val tl = List.tl
end
structure LazyList : MYLIST =
struct
datatype 'a t = Nil | Cons of 'a * (unit -> 'a t)
val empty = Nil
fun null Nil = true
| null _ = false
fun cons (x, xs) = Cons (x, fn () => xs)
fun hd Nil = raise Empty
| hd (Cons (x, _)) = x
fun tl Nil = raise Empty
| tl (Cons (_, f)) = f ()
end
structure ConcatList : MYLIST =
struct
datatype 'a t = Nil | Singleton of 'a | Concat of 'a t * 'a t
val empty = Nil
fun null Nil = true
| null (Singleton _) = false
| null (Concat (xs, ys)) = null xs andalso null ys
fun cons (x, xs) = Concat (Singleton x, xs)
fun hd Nil = raise Empty
| hd (Singleton x) = x
| hd (Concat (xs, ys)) = hd xs
fun tl Nil = raise Empty
| tl (Singleton x) = Nil
| tl (Concat (xs, ys)) = (* exercise *)
end
signature MYLISTCOMB =
sig
type 'a t
val length : 'a liste -> int
val map : ('a -> 'b) -> 'a liste -> 'b liste
val foldl : ('a * 'b -> 'b) -> 'b -> 'a liste -> 'b
val append : 'a liste * 'a liste -> 'a liste
val concat : 'a liste liste -> 'a liste
val sort : ('a * 'a -> order) -> 'a t -> 'a t
end
functor ListComb (X : MYLIST) : MYLISTCOMB =
struct
type 'a t = 'a X.t
open X
fun length xs =
if null xs then 0
else 1 + length (tl xs)
fun map f xs =
if null xs then empty
else cons(f (hd xs), map f (tl xs))
fun foldl f e xs =
if null xs then e
else foldl f (f (hd xs, e)) (tl xs)
fun append (xs, ys) =
if null xs then ys
else cons (hd xs, append (tl xs, ys))
fun concat xs =
if null xs then empty
else append (hd xs, concat (tl xs))
fun sort cmp xs = (* exercise *)
end
structure RegularListComb = ListComb (RegularList)
structure LazyListComb = ListComb (LazyList)
structure ConcatListComb = ListComb (ConcatList)