Sml 一个标准的ML函子可以接受另一个函子作为参数吗?
我有一个集和映射作为非平衡二叉树的实现。因为集合和映射非常相似,我实际上只从零开始为映射编写了一个实现,然后将集合作为从键到单元的映射来实现:Sml 一个标准的ML函子可以接受另一个函子作为参数吗?,sml,functor,ml,Sml,Functor,Ml,我有一个集和映射作为非平衡二叉树的实现。因为集合和映射非常相似,我实际上只从零开始为映射编写了一个实现,然后将集合作为从键到单元的映射来实现: signature EQ = sig type t; val eq : t * t -> bool; end; signature ORD = sig include EQ; val lt : t * t -> bool; end; signature SET = sig structure Elem : EQ;
signature EQ =
sig
type t;
val eq : t * t -> bool;
end;
signature ORD =
sig
include EQ;
val lt : t * t -> bool;
end;
signature SET =
sig
structure Elem : EQ;
type set;
val empty : set;
val member : Elem.t * set -> bool;
val insert : Elem.t * set -> set option;
end;
signature MAP =
sig
structure Key : EQ;
type 'a map;
val empty : 'a map;
val lookup : Key.t * 'a map -> 'a option;
val insert : Key.t * 'a * 'a map -> 'a map option;
end;
functor UnbalancedMap (Key : ORD) :> MAP =
struct
structure Key = Key;
datatype 'a tree = E | T of Key.t * 'a * 'a tree * 'a tree;
type 'a map = 'a tree;
val empty = E;
fun lookup (k, t) =
let
fun loop (k, E, E) = NONE
| loop (k, E, T (x, y, _, _)) =
if Key.eq (k, x) then SOME y
else NONE
| loop (k, t as T (x, _, a, b), r) =
if Key.lt (k, x) then loop (k, a, r)
else loop (k, b, t);
in
loop (k, t, E)
end;
fun insert (k, v, t) =
let
exception Exists;
fun loop (k, v, E, E) = T (k, v, E, E)
| loop (k, v, E, T (x, _, _, _)) =
if Key.eq (k, x) then raise Exists
else T (k, v, E, E)
| loop (k, v, t as T (x, y, a, b), r) =
if Key.lt (k, x) then T (x, y, loop (k, v, a, r), b)
else T (x, y, a, loop (k, v, b, t));
in
SOME (loop (k, v, t, E)) handle Exists => NONE
end;
end;
functor UnbalancedSet (Elem : ORD) :> SET =
struct
structure Map = UnbalancedMap (Elem);
structure Elem = Map.Key;
type set = unit Map.map;
val empty = Map.empty;
fun member (x, t) = case Map.lookup (x, t) of
NONE => false
| _ => true;
fun insert (x, t) = Map.insert (x, (), t);
end;
假设我提出了另一个使用其他数据结构的地图实现。然后,我应该能够重用该数据结构,将集合定义为从键到单元的映射:
functor AnotherMap (Key : EQ) :> MAP =
struct
(* ... *)
end;
functor AnotherSet (Elem : EQ) :> SET =
struct
structure Map = AnotherMap (Elem);
structure Elem = Map.Key;
type set = unit Map.map;
val empty = Map.empty;
fun member (x, t) = case Map.lookup (x, t) of
NONE => false
| _ => true;
fun insert (x, t) = Map.insert (x, (), t);
end;
然而,如果我提出任意多个地图的实现,重新定义使用与这些地图相同的数据结构的集合很快就会变得单调乏味。我真正想要的是一个函子,它将一个函子从X映射到MAP,并生成一个从X到SET的函子,其中X是包含EQ(或者EQ本身)的任何签名。这在标准ML中可能吗?作为非标准扩展,是的。我相信您正在寻找的功能被SML/NJ称为“高阶函子”。这里有一些关于它们实现的限制 不过,我强调这不是SML的标准特性。直接使用SML模块系统无法实现这一点