dictionary - 尝试返回 Map 元组时无法理解错误
问题描述
首先,我有这些类型:
type position = float * float
type node = position
我已经编写了这些模块来制作我的地图:
module MyMap =
struct
type t = Graph.node
let compare (a1,b1) (a2,b2) =
if a1 > a2 then 1
else if a1 < a2 then -1
else if b1 > b2 then 1
else if b1 < b2 then -1
else 0
end
module DistMap = Map.Make(MyMap)
然后我写了这个函数:
let update_distances n1 n2 dMap prevMap =
if ((DistMap.find n2 dMap) > (DistMap.find n2 dMap) +. extract_float(dist2 n1 n2)) then
((DistMap.add n2 (DistMap.find n2 dMap) dMap), DistMap.add n1 prevMap)
else (dMap,prevMap)
extract_float(dist n1 n2)
n1
返回从和n2
节点之间的距离提取的浮点数。
为了更清楚地说明,dMap 是应该像这样构建的 (node, float) 而 prevMap 是应该像这样构建的映射: (node,node)。
我的目标是能够返回一个 Map 元组,无论是否修改,具体取决于 if 语句,但这是我得到的错误输出:
Error: This expression has type 'a but an expression was expected of type
'a DistMap.t -> 'a DistMap.t
The type variable 'a occurs inside 'a DistMap.t -> 'a DistMap.t
更新 :
该dist2
函数具有类型distance
。
type distance = Distance of float
这里是extract_float
let extract_float dist =
match dist with
| Distance x -> x
这是我第一次看到这个错误,无论如何要解决这个问题?
谢谢。
解决方案
处理类型错误的第一步是尝试恢复一些上下文类型信息。
在这里,类型检查器在 prevMap 部分报告错误
else dMap,prevMap
错误:此表达式的类型为 'a,但预期的表达式类型为 'a DistMap.t -> 'a DistMap.t
类型变量 'a 出现在 'a DistMap.t -> 'a DistMap.t
此外,错误是元组的第二个元素的预期类型与实际类型不匹配。由于我们正在输入一个else
分支,这意味着错误从then
分支中开始,并且稍后才引发冲突。所以让我们看一下then
分支(我们现在可以忽略recursive occurrence
消息的一部分):
then DistMap.add n2 (DistMap.find n2 dMap) dMap, DistMap.add n1 prevMap
由于元组的第二个元素引发了错误,我们可以将错误的可能根缩小到
DistMap.add n1 prevMap
此时,我们可以询问类型DistMap.add
:
node -> 'data -> 'data DistMap.t -> 'data DistMap.t
换句话说,从这里的第一次使用prevMap
,我们和类型检查器可以推断出:
- prevMap是一些要存入的数据
DistMap.t
- 元组的第二个元素是添加
prevMap
到 a的函数DistMap.t
在这一点上一切都很好,但随后在
else dMap, prevMap
我们知道这prevMap
也是一个函数。a 中的prevMap
一些数据和 type 的更新函数也是如此。这两种类型是不兼容的(如果不允许递归类型)。因此错误消息的第一部分是'a
'a DistMap.t
'a DistMap.t -> 'a DistMap.t
错误:此表达式的类型为 'a,但预期的表达式类型为 'a DistMap.t -> 'a DistMap.t
但是,错误消息的第二部分呢:
类型变量 'a 出现在 'a DistMap.t -> 'a DistMap.t
碰巧OCaml
可以使这两种类型与-rectypes
选项兼容,那么类型prevMap
就是奇异的:
'a DistMap.t -> 'a DistMap.t as 'a
这意味着这prevMap
是一个转换的函数,DistMap.t
其中包含转换的函数,DistMap.t
其中包含...的函数
这种递归类型很少使用,使用时它们可以掩盖普通的编程错误。因此默认情况下它们被禁用,并且类型检查器在禁用recursive occurrence
时推断递归类型时会引发消息-rectype
。
推荐阅读
- r - 运行数据框然后将乘数应用于 R 中的某些行
- php - 在 Woocommerce 中添加多个自定义订单状态
- python - 在 Python 中使用正则表达式获取 txt 文件中的文本块
- keras - 如何打印 Keras 嵌入的权重?
- ruby-on-rails - 在 Rails 中迭代 CSV,记录错误但不停止循环
- mysql - 以下 MySql 查询有什么问题?
- excel - Excel VBA 代码在一台计算机之外工作 - 错误 91
- linux - 为什么linux内核TCPIP堆栈不使用一些设计模式来处理skb,比如责任链?
- c++ - 导入 cstring 失败:包括
错误 - python - 如何迭代由对象组成的 numpy.ndarray?还对它们应用各种功能