如何使模块符合OCaml签名

时间:2014-12-25 17:02:33

标签: ocaml

我正在使用ocaml制作海龟图形程序。这需要提供符合以下OCaml签名的模块实现。

type program
type ins

val mf: float -> ins
val mb: float -> ins
val tl: float -> ins
val tr: float -> ins
val pu: ins
val pd: ins
val repeat: int -> program -> ins
val make_program: ins list -> program

type stroke
val strokes: program -> stroke list

type state
val animate: program -> state list

val strokes': program -> unit
val animate': program -> unit
  • 定义乌龟程序和乌龟指令的类型。
  • mf,mb,tl,tr,pu,pd,repeat和make_program函数是 用来建立说明和程序。
  • 定义笔画类型。
  • 编写一个函数笔划,给定一个乌龟程序,返回 乌龟绘制的笔画列表。
  • 定义乌龟状态的类型。
  • 编写一个函数动画,给定一个乌龟程序,返回 乌龟的状态列表。
  • 笔画'和动画'渲染笔画和海龟动画

这是我的mfpupd的代码:

type turtle = {
    mutable x : float;
    mutable y : float;
    mutable phi : float;
    mutable stt : int;
}

let round = int_of_float

let pi = 3.1415926535897932384626433832795

let rad_of_deg a = a *. pi /. 180.

let p = { x = 100.; y = 100.; phi = 0.; stt = 1 }

let pu() =
    p.stt <- 0

let pd() =
    p.stt <- 1

let mf l = 
        let x2 = (p.x) +. l *. cos (rad_of_deg p.phi)
        and y2 = (p.y) +. l *. sin (rad_of_deg p.phi) in
        moveto (round p.x) (round p.y);
        if (p.stt == 1) then lineto (round x2) (round y2);
        p.x <- x2;
        p.y <- y2

mf的输出是: val mf: float -> unit = <fun>

我的问题是如何使它看起来像要求?

1 个答案:

答案 0 :(得分:0)

我会尝试给你一些提示,但你应该考虑学习OCaml教科书。我不会在几次击键时教你OCaml,不是因为我不想,而是因为这是不可能的。

在OCaml中,编译单元由两部分组成:

  • 模块实施
  • 模块签名

模块实现由值和类型组成,每个值都有一个与之关联的类型。 OCaml将为您推断值的类型,但您可以使用类型注释来帮助它。

应将实现放在扩展名为.ml的文件中。签名应放在.mli扩展名的文件中。如果它们共享相同的名称并为您构建编译单元,OCaml编译器将同时使用它们,以后可以将它们链接到可执行文件中。

例如,您可以将上面给出的签名放入名为gr.mli的文件中。然后,您需要编写一个将实现此接口的文件。您必须将此文件命名为gr.ml并将您的类型和值放入其中。然后你可以使用

编译它
ocamlbuild gr.cmo

和OCaml编译器将检查您的实现是否实际实现了给定的签名。为了符合签名,您的模块应包含签名中指定的所有值和类型,它们的类型应相同。实际上,您的实现可以包含更多值,并且值的类型可以比签名中指定的更为通用,但是我们会走得很远。

您在示例中显示的内容(我引用val mf: float -> unit = <fun>)实际上是OCaml顶级解释器的输出。它由三部分组成(我使用大写字母表示这是模式的可变部分):

val NAME : TYPE = VALUE

其中NAME是值的名称(在您的情况下是mf),TYPE是其推断类型(在您的情况下为float -> unit),以及{ {1}}是值的可打印表示。由于函数没有可打印的表示,因此在您的情况下它被表示为VALUE。您可以将定义的类型与所需定义的类型进行比较(即<fun>)。如果类型float -> ins等于类型ins,则很难猜测这些类型可以相等。是否真实取决于您的实施。

我希望,这会对你有所帮助。但这不是阅读教科书。我只想给你开始提示。