- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想了解 OCAML 对象这种行为的原因。假设我有一个类(class) A
调用另一个类的对象的方法B
.从原理上讲,A#f 调用 B#g 和 B#h。 OOP 中的常规做法是我想避免将 B 用作固定的具体类,而是只为 B 声明一个接口(interface)。在 OCAML 中执行此操作的最佳方法是什么?我尝试了几种选择,但我不太明白为什么其中一些有效而另一些无效。以下是代码示例。
版本 1:
# class classA = object
method f b = b#g + b#h
end ;;
Error: Some type variables are unbound in this type:
class a : object method f : < g : int; h : int; .. > -> int end
The method f has type (< g : int; h : int; .. > as 'a) -> int where 'a
is unbound
b
具有开放对象类型
<g:int;h:int;..>
但随后提示我的类没有声明任何类型变量。所以看来
classA
需要有类型变量;然后我明确地介绍了一个类型变量。
# class ['a] classA2 = object
method f (b:'a) = b#g + b#h
end ;;
class ['a] classA2 :
object constraint 'a = < g : int; h : int; .. > method f : 'a -> int end
'a
也令人困惑。 ,但我仍然可以说
let x = new classA2
未指定
'a
的类型值.为什么会这样?
classA2
的另一个缺点是一个显式类型约束
(b:'a)
包含一个类型变量。毕竟我知道
b
必须符合固定接口(interface)而不是未知类型
'a
.我希望 OCAML 验证这个接口(interface)确实是正确的。
classB
作为类类型,然后声明
b
必须是这种类型:
# class type classB = object method g:int method h:int end;;
class type classB = object method g : int method h : int end
# class classA3 = object method f (b:classB) = b#g + b#h end;;
class classA3 : object method f : classB -> int end
classA3
需要显式多态了吗?
new classA2
未指定 'a
的类型即使 classA2
用类型变量声明 'a
? classA3
接受类型约束 (b:classB)
并且不再需要绑定(bind)类型变量? classA2
的功能吗?和 classA3
以某种微妙的方式有所不同,如果是,如何? 最佳答案
这会有点复杂,所以请坚持。首先,让我添加一个 classA4
变体,这恰好是您真正需要的。
class classA4 = object
method f : 'a. (#classB as 'a) -> int = fun b -> b#g + b#h
end
classA2
,
classA3
和
classA4
都是有细微差别的,区别在于OCaml如何对待类型多态和对象多态。假设有两个类
b1
和
b2
, 执行
classB
类型。
b1
类型的表达式可以强制输入
classB
使用强制语法
(new b1 :> classB)
.这种类型强制会丢弃类型信息(您不再知道对象的类型为
b1
),因此必须明确说明。
b1
可用于替代任何具有约束
#classB
的类型变量(或
< g : int ; h : int ; .. >
)。这不会丢弃任何类型信息(因为类型变量被实际类型替换),因此它由类型推断算法执行。
f
的
classA3
需要
classB
类型的参数,这意味着强制类型转换:
let b = new b1
let a = new classA3
a # f b (* Type error, expected classB, found b1 *)
a # f (b :> classB) (* Ok ! *)
classB
的类可以使用。
f
的
classA2
期望与约束
#classB
匹配的类型的参数,但是 OCaml 要求这样的类型不应该是未绑定(bind)的,所以它是在类级别绑定(bind)的。这意味着
classA2
的每个实例将接受
的参数单实现
classB
的任意类型(并且该类型将被类型推断)。
let b1 = new b1 and b2 = new b2
let a = new classA2
a # f b1 (* 'a' is type-inferred to be 'b1 classA2' *)
a # f b2 (* Type error, because b1 != b2 *)
classA3
相当于
classB classA2
,这就是为什么它不需要绑定(bind)类型变量的原因,也是为什么它的表达力严格低于
classA2
.
f
的
classA4
已使用
'a.
给出显式类型语法,它在方法级别而不是类级别绑定(bind)类型变量。它实际上是一个通用量词,这意味着 « 可以为任何类型调用此方法
'a
实现
#classB
» :
let b1 = new b1 and b2 = new b2
let a = new classA4
a # f b1 (* 'a is chosen to be b1 for this call *)
a # f b2 (* 'a is chosen to be b2 for this call *)
关于oop - 为什么使用类类型时,OCAML 对象中未绑定(bind)的类型变量不出现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11177125/
我正在尝试以更命令的方式表达一组链式调用。例如,图像我们有一个函数,它接受一个列表和一个元素,并将该元素附加到列表的末尾: let insert l e = l @ [e] 我想一次插入几个元素。
是否有一个完整的列表(或详尽的规则)可以给 OCaml 中的自定义中缀运算符提供可能的名称? 最佳答案 如 OCaml manual 中所述, 中缀运算符必须匹配正则表达式 [-=<>@^|&+*/$
我想开始使用 OCaml 编程。由于我是 Windows 用户,我知道最好使用 Netbeans 的 OCaml 插件。 我已经从以下链接下载了上述插件:http://ocamlplugin.loki
能够做到这一点以获得最大速度不是很重要吗? 编辑: 例如,Clojure 有 map ,它使用多个核心。 Harrop 博士写道(2011 年 1 月 9 日): 语言中添加的新功能,例如一流 OCa
我在 x86 机器上用字节码编译 OCaml 程序,然后将字节码传输到 ppc64 机器。假设 ppc64 机器有 ocamlrun(为 ppc64 编译),我能在 ppc64 架构上执行我的程序吗?
我创建了一个新模块,它只是名称很长的模块的较短别名: module M = ModuleWithLongName 我处于最终可执行文件的大小很重要的情况。上面的构造是由编译器合理处理的吗(即 M 实际
我在使用 ocaml 时遇到了麻烦。 我想创建一个函数,每次调用它时都会增加我的计数器,并将我的 vargen 字符串与计数器编号连接起来,然后返回这个新字符串。 我没有成功的做法是: let (co
我正在学习 OCaml,我对变量的不变性有点困惑。根据我正在阅读的书,变量是不可变的。到目前为止一切顺利,但为什么我可以这样做: let foo = 42 let foo = 4242 我错过了什么?
非尾递归组合函数可以这样写: let rec combinations l k = if k List.length l then [] else if k = 1 then List.ma
我有一段包含camlp4引用的代码。 let f_name = "my_func" > 运行此程序后 camlp4of ,它产生这个: Ast.StExp (_loc, (Ast.ExAp
如何在 OCaml 中模拟这个 Python 习语? if __name__=="__main__": main() 见 RosettaCode其他编程语言中的示例。 最佳答案 Ocaml 中没
我开始学习 Ocaml,使用 hickey book ,我被困在练习 3.4,第 9 部分 让 x x = x + 1 在 x 2 运算结果为3 ,但我不明白为什么? 最佳答案 当你写 let x x
Rust具有线性系统。有什么(好的)方法可以在 OCaml 中模拟这个吗?例如,当使用 ocaml-lua 时,我想确保仅当 Lua 处于特定状态(堆栈顶部的表等)时才调用某些函数。 编辑 :这是最近
在 OCaml?我知道非常酷的Bitstring图书馆,但是 虽然这将是在某些协议(protocol)中解析二进制数据的好方法, 它不支持异或或移位等按位运算。 我相信该库使用的底层数据结构是 只是
我们可以像这样构造一个无限列表: let rec endless = 1::endless 我认为它会吃掉所有的内存,但是当我在 utop 中尝试时,好像不是这样。 utop显示列表已构建: val
是否可以通过合并列表的元素而不是创建列表的列表来创建列表? 例子: List.combine ["A";"B"] ["C";"D"];; 我得到: [("A", "C"); ("B", "D")] 有
我想在 OCaml 中创建一个查找表。该表将有 7000 多个条目,在查找时(通过 int)返回一个字符串。用于此任务的适当数据结构是什么?表是否应该从基本代码中外部化,如果是这样,如何“包括”查找表
我正在评估 Ocaml 顶层中的一段非常简单的代码: let p5 () = print_int 5;; p5 ();; print_string "*************************
记录和元组之间是否有任何区别而不仅仅是句法差异? 有性能差异吗? 元组和记录的实现是否相同? 您是否有可以使用元组完成但不能使用记录完成的事情的示例(和 反之)? 最佳答案 模数语法它们几乎相同。主要
OCaml 中的 ` 运算符有什么作用? let int_of_meth = function | `GET -> 0 | `POST -> 1 | `PUT ->
我是一名优秀的程序员,十分优秀!