在Lua中有一个简短的表示法,用于将“self”发送到函数,因此a.withdraw(a, 100.0)
可以写成a:withdraw(100.0)
。是不是可以对OCaml进行类似的扩展,让List.length l
写成l::length
并List.map (fun e -> e + 1) l
写成l::map (fun e -> e + 1)
?
答案 0 :(得分:4)
几个月前,Fabrice Le Fessant就ocaml bugtracker提出了这个问题:PR#6012 object-like notation for module functions,受到他在wxOCaml图书馆工作的启发(参见设计说明in this PDF)。 / p>
功能请求产生了一个讨论(请参阅PR#6012链接进行讨论),但我认为共识是这不是一个好主意。人们不满意添加特定的语言功能来支持使模块编程类似于对象编程。
我认为你可以将这个想法分解成各自独立的小块,但是需要更多的工作才能被充分理解,以便在成熟的编程语言中进行整理。例如,你暗示某种形式的代码推断。
答案 1 :(得分:2)
List
是一个ocaml模块,而不是ocaml对象。当您编写List.length
时,您调用属于模块列表的函数length
(请参阅模块作为名称空间或库,以获得第一个直觉)。
来自doc,
模块的主要动机是将相关定义(例如数据类型的定义和该类型的相关操作)打包在一起,并为这些定义强制实施一致的命名方案。这可以避免名称耗尽或意外混淆名称。
此外,对于一个对象,您需要在使用之前创建一个(使用new)(在其上调用函数f,例如myobject # f
),
示例,来自文档here,
我们现在创建一个新的点p,即点类的实例。
# let p = new point;;
val p : point = <obj>
我们现在调用p:
的一些方法# p#get_x;;
- : int = 0
答案 2 :(得分:2)
如果查看这个syntax directory,你会发现我在wxOCaml上下文中编写的camlp4语法扩展(它位于wxOCaml的分支“wx-syntax”中)。
目前的语法是
module x -> M in E
您可以使用
x->f
而不是
M.f x
在表达式E中的我认为后一种语法实际上很好,但我建议改变第一种语法:
let module x -> M in E
取悦压头。语法文件“pa_wx.ml”简短且易于修改,您可以在第563行的“drawing.ml”中看到生成的代码。
答案 3 :(得分:1)
不是很优雅,因为OCaml值和类型都不归模块所有。即使我们知道表达式的完整类型,我们也不知道默认情况下该函数应该从哪个模块中获取。
在代表l->length
的示例List.length l
中,编译器需要知道我们的想法是l
属于模块List
(它甚至不提供内置类型'a list
)的类型别名。或者我们的意思是Batteries.List.length
。
因此,需要声明“l使用模块列表”。