在OCaml中扩展一个来自Map模块的模块

5

我有一个模块StringMap,由函数对象Map.Make构建,给定了一个类型String

module StringMap = Map.Make(String)

除了Map提供的普通操作之外,我想在这个模块中添加更多的定义,例如my_own_function,以便我可以调用StringMap.my_own_function。 有人知道我应该在哪里定义这种函数及其签名吗?

1个回答

9

你可以在新模块内使用 include 关键字来添加所有相同的函数。这也在 OCaml 3.12 中被扩展到签名

module StringMap =
    struct
        include Map.Make(String)
    end

如果你想访问地图的结构,你需要添加一些Obj.magic或者特殊外部函数%identity。由于没有类型检查,所以类型的重新定义必须是准确的。

module Make (Ord : Map.OrderedType) =
    struct
        include Map.Make(Ord)

        type 'a impl = Empty 
                     | Node of 'a impl * key * 'a * 'a impl * int

        external impl_of_t : 'a t -> 'a impl = "%identity"
        external t_of_impl : 'a impl -> 'a t = "%identity"

        let cardinal map =
            let rec cardinal = function
                | Empty -> 0
                | Node(l,_,_,r,_) -> cardinal l + 1 + cardinal r
            in
            cardinal (impl_of_t map)

    end

这不是你想向询问Caml问题的初学者展示的东西。我认为把它呈现得像是合理做法并不是个好主意。如果你希望介绍平衡树实现,请去介绍(Batteries通过BatAvlTree来实现),但是破坏抽象并不是一个好主意... - gasche
完全同意,希望他发现答案的第一部分足以满足他的需求。 - nlucaroni
@gasche: 你是指回答的第二部分吗?使用include的第一部分被认为是惯用语吗? - tokland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接