如何使模块符合OCaml签名
我正在使用ocaml制作一个海龟图形程序。这需要提供符合以下OCaml签名的模块实现如何使模块符合OCaml签名,ocaml,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 li
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
- 为turtle程序和turtle指令定义类型
- mf、mb、tl、tr、pu、pd、repeat和make_程序功能为 用于生成指令和程序
- 定义笔划的类型
- 编程一个函数,给定一个turtle程序,该函数返回 海龟画的笔画列表
- 为海龟的状态定义一个类型
- 编程一个函数,在给定海龟程序的情况下,该函数将返回 海龟的状态列表
- “笔划”和“动画”渲染笔划和海龟动画
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
type海龟={
可变x:浮动;
可变y:浮动;
可变phi:浮动;
可变stt:int;
}
让round=int\u/u浮动
设pi=3.1415926535897932384626433832795
设a度的rad_=a*。pi/。180
设p={x=100;y=100;phi=0;stt=1}
让浦()=
P.STT我会给你一些提示,但是你应该考虑学习OCAML教科书。我不会用几个按键来教你OCaml,不是因为我不想,而是因为这是不可能的
在OCaml中,编译单元由两部分组成:
- 模块实现
- 模块签名
模块实现由值和类型组成,每个值都有一个与之关联的类型。OCaml将为您推断值的类型,但您可以使用类型注释来帮助它
实现应该放在扩展名为.ml
的文件中。签名应放在扩展名为.mli
的文件中。如果它们共享同一个名称并为您构建一个编译单元,那么OCaml编译器将同时使用这两个单元,以后可以将其链接到可执行文件中
例如,您可以将上面给定的签名放入名为gr.mli
的文件中。然后您需要编写一个文件来实现这个接口。必须将此文件命名为gr.ml
,并将类型和值放入其中。然后可以使用
ocamlbuild gr.cmo
OCaml编译器将检查您的实现是否实际实现了给定的签名。为了符合签名,您的模块应该包含签名中指定的所有值和类型,并且它们的类型应该相同。事实上,您的实现可以包含更多的值,并且值的类型可以比签名中指定的更通用,但是我们要做的远远不止这些
您在示例中显示的内容(我指的是valmf:float->unit=
)实际上是OCaml顶级解释器的输出。它由三部分组成(我用大写字母表示这是模式的可变部分):
其中,NAME
是一个值的名称(在您的例子中,它是mf
),TYPE
是它的推断类型(float->unit
,在您的例子中),value
是该值的可打印表示形式。因为函数没有可打印的表示形式,所以在您的例子中,它被表示为
。您可以将定义的类型与所需定义的类型进行比较(即,float->ins
)。如果typeins
等于typeunit
,就不难猜测这些类型可以相等。它是否正确取决于您的实现
我希望这会对你有所帮助。但这并不能代替阅读课本。我只是想给你一些开始的提示。问题是?如何构建符合上述Ocaml特征的模块?从我看到的问题是,你的函数mf
返回unit
,你希望它返回ins
。但是,ins
是什么类型的呢?它是一种抽象类型,这意味着您将在实现中指定它是什么,但不会在模块接口中显示它。因此,在回答So可以帮助解决的问题之前,您需要做一些工作。向我们展示您的代码,并告诉我们签名的含义(特别是类型ins
代表的含义)。已编辑。对不起,我犯了这个错误。我必须用上面的签名建立一个海龟图形程序。你能帮助我吗?
val NAME : TYPE = VALUE