- 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/
我有一个 foo 类,它有一个 bar 方法,它接受可调用的东西(函数指针/仿函数)。这个可调用的东西应该作为绑定(bind)元素传递给另一个方法 doit 和第三个方法 bar_cb 方法。 #in
我正在尝试在我的 WPF 4.0 应用程序(使用 VS 2010 Pro RTM)中创建自定义 TabItem 模板/样式,但尽管一切似乎都正常工作,但我注意到跟踪窗口中存在绑定(bind)错误。 我
作为一名刚接触 Android 的开发人员,我想我可能误解了绑定(bind)服务。 我创建了一项服务来结束对服务器的访问。作为此服务的一部分,该服务正在监听多播地址,以识别本地网络上的设备何时出现和消
这个问题在这里已经有了答案: What is the use of the JavaScript 'bind' method? (23 个回答) 关闭 7 年前。 所以我一直在尝试了解一些 JS 上
我不明白这三种语法之间的区别: where a = f (b) do a <- f (b) do let a = f (b) 我确实明白了a <- f(b)与其他两个不同,在大多数情况下,我尝试了所有
我在将 Cocoa 项目从手动同步接口(interface)模型转换为绑定(bind)模型时遇到问题,这样我就不必担心接口(interface)粘合代码。 我关注了 CocoaDevCentral C
我正在尝试找出一种好的方法来对处理大数据集的代码进行并行化,然后将结果数据导入 RavenDb。 数据处理受 CPU 限制和数据库导入 IO 限制。 我正在寻找一种解决方案,以对 Environmen
我正在 foreach 循环中生成单选按钮。我试图将选中的属性绑定(bind)到父级中的基本可观察值。不幸的是,当单击单选按钮时,父级的属性似乎没有在单击处理程序中更新。 基于一些previous w
在我的 Windows Phone 应用程序中,我有两个 LongListSelectors并排在页面上。我想做到这一点,以便当用户滚动其中一个时,另一个滚动相同的量。 两个 LongListSele
我在网上看到这个问题准备面试: Given a non-preemptive kernel which type of process will get affected morein terms o
我有一个 foreach 绑定(bind),如下所示: Summary Permitting 原因是有两个选项卡始终存在,并且我根据是否添加了其他选项卡来添加其他选项
任何人都有绑定(bind)相同的情况DataContext到 TextBlock 中的 Text 属性(例如)。 我必须分配 DataContext以我的风格反射(reflect)基于 Datacon
给定以下代码: Login 和下面的javascript $(function () { $('#btnLogin').click(function () { co
我使用 boost::asio 创建了一个服务器。我在绑定(bind)到端点时遇到问题。所以,如果我在构造函数中初始化一个接受器: Server::Server(QWidget *parent) :
我正在将现有项目从 MySQL 转换为 Postgres。代码中有相当多的原始 SQL 文字使用 ? 作为占位符,例如 SELECT id FROM users WHERE
似乎在绑定(bind)某些数据时出错了,有人可以帮我解决我哪里出错了,尽管我无法弄清楚。 真的不需要在这里显示太多,这是 Binding,我已经通过移除背景并在其中放置颜色来测试背景,效果很好。 编辑
我正在尝试使用 wcf 构建一个 http 监听器(web 服务)。这个监听器是一个更大的桌面应用程序的一部分。此桌面应用程序还会调用 http 监听器。 当监听器接收到数据时,它应该被传递到桌面应用
嘿嘿。 我正在使用 Node.JS 和 child_process 来生成 bash 进程。我试图了解我是否正在执行 I/O 绑定(bind)、CPU 绑定(bind)或两者兼而有之。 我正在使用 p
尝试执行以下操作并出现“Got interpolation ({{}}) where expression was expected”错误。 {{item.name}} 谢谢!
我有一个导入的 Java 库,它是我解决方案中的“绑定(bind)库”项目。 我正在尝试从解决方案中的另一个项目绑定(bind)到第 3 方库中的服务。 第 3 方库文档 [在 java 中] 非常简
我是一名优秀的程序员,十分优秀!