使用Make语法在OCaml中定义自己的数据结构

时间:2014-05-18 22:46:32

标签: ocaml

在尝试使用OCaml中的Purely Functional Data Structures实现练习时,我不确定如何创建解决方案的实例。

说我有以下代码:

    module type Stack =
      sig
        type 'a t
        val empty   : 'a t
        val isEmpty : 'a t -> bool
        val cons    : 'a -> 'a t -> 'a t
        val head    : 'a t -> 'a
        val tail    : 'a t -> 'a t
    end

    (* Implementation using OCaml lists *)
    module MyStack : Stack = struct
      type 'a t = 'a list

      exception Empty

      let empty = []
      let isEmpty l =
        match l with
        | [] -> true
        | _  -> false

      let cons x l = x :: l

      let head l =
        match l with
        | h :: _ -> h
        | [] -> raise Empty

      let tail l =
        match l with
        | _ :: r -> r
        | [] -> raise Empty
    end

我想提供一个类似于Set.Make(String)的Make函数来创建一个专门的实例。 但我不知道该怎么做。

1 个答案:

答案 0 :(得分:2)

在我看来,按顺序概念参数化一个集合是很自然的(或者你可以通过平等来逃避)。但是堆栈不需要以这种方式参数化;即,它不依赖于秩序或平等的概念。它只取决于其结构的代数性质。

您已经拥有一个参数化多态模块,可用于制作任何类型对象的堆栈。

我正在查看Set模块的代码。如果你想制作像Set.Make这样的仿函数,你需要一个元素的模块类型。既然你可以使用任何类型(不像Set,需要一个有序的类型),你可以使用这样的东西:

module type AnyType = struct type t end

那么你的仿函数可能看起来像这样(再次,我只是从Set模块中复制代码):

module Make(Any: AnyType) =
    struct
    type elt = Any.t
    type t = elt list
    ...
    end

<强>更新

如果你只是想按原样试用堆栈代码,你可以开始使用它:

$ ocaml
        OCaml version 4.01.0

# #use "mystack.ml";;
module type Stack =
  sig
    type 'a t
    val empty : 'a t
    val isEmpty : 'a t -> bool
    val cons : 'a -> 'a t -> 'a t
    val head : 'a t -> 'a
    val tail : 'a t -> 'a t
  end
module MyStack : Stack
# let x = MyStack.cons 3 MyStack.empty;;
val x : int MyStack.t = <abstr>
# MyStack.head x;;
- : int = 3
#