list - OCaml 和 ReasonML 的结果不同
问题描述
有一种情况将两个向量映射为一个向量。我预计两个 ML 的结果应该是相同的。不幸的是,ReasonML 的结果是不同的。请帮助并评论如何解决它。
OCaml
List.map2 (fun x y -> x+y) [1;2;3] [10;20;30];;
[11;;22;;33]
原因机器学习
Js.log(List.map2 ( (fun (x,y) => x+y), [1,2,3], [10,20,30]))
[11,[22,[33,0]]]
解决方案
结果是相同的,但是您使用了不同的打印方法。如果Js.log
您不使用rtop
or sketch.sh,您将获得您期望的输出:
- : list(int) = [11, 22, 33]
Js.log
打印它的方式不同,因为它是一个 BuckleScript 绑定到console.log
,它将打印你给它的值的JavaScript 表示。JavaScript 中不存在列表,只有数组存在。
BuckleScript 表示列表的方式与它在本地完成的方式几乎相同。OCaml 和 Reason 中的列表是一个“cons-cell”,它本质上是一个元组或 2 元素数组,其中第一项是该单元格的值,最后一项是指向下一个单元格的指针。list
类型本质上是这样定义的:
type list('a) =
| Node('a, list('a))
| Empty;
有了这个定义,可以用以下方式构建:
Node(11, Node(22, Node(33, Empty)))
它在 JavaScript 中表示如下:
[11,[22,[33,0]]]
^ ^ ^ ^
| | | The Empty list
| | Third value
| Second value
First value
列表是这样定义的,因为不变性使得这种表示非常有效。因为我们可以添加或删除值,而无需将旧列表中的所有项目复制到新列表中。要添加一个项目,我们只需要创建一个新的“cons-cell”。使用具有想象中的不变性的 JavaScript 表示:
const old = [11,[22,[33,0]]];
const new = [99, old];
并且要从前面移除一个项目,我们不需要创建任何东西。我们可以只获得对子列表的引用并重新使用它,因为我们知道它不会改变。
const old = [11,[22,[33,0]]];
const new = old[1];
列表的缺点是在末尾添加和删除项目相对昂贵。但在实践中,如果您以函数式的方式构建代码,使用递归,列表将非常自然地使用。而且效率很高。
推荐阅读
- c++11 - CUDA:如何使用 barrier.sync
- python - 从 HTML 获取链接(Selenium 和 Python)
- c# - 升级到 asp.net core 2.2 后的空 href
- three.js - 如何在 WEBGL 中使用 gl_LastFragData?
- javascript - 在 d3v4 的 scalelog 中使用来自 JSON 数据的日期
- java - 通过 Java Socket 和 ServerSocket 类连接到服务器
- apache-spark - RDD和传统的关系数据库系统有什么区别
- python - tensorflow Object_Detection 通过model_main.py训练,出现TypeError
- asp.net - 为什么我应该在 Web 配置中使用 customErrors 模式“关闭”?
- ios - 在 CollectionView 中解码时出现 JSON 解码器错误