我正在使用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
,pu
和pd
的代码:
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>
我的问题是如何使它看起来像要求?
答案 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
,则很难猜测这些类型可以相等。是否真实取决于您的实施。
我希望,这会对你有所帮助。但这不是阅读教科书。我只想给你开始提示。