expression - 通用列表类型的 ocaml 类型错误 (ide * 'a)
问题描述
我正在编写一个 OCaml 解释器,我会检查成对列表中是否有重复项。
type exp = ... | Dict of (ide * exp) list | AddPair of exp * (ide * exp) list;;
type evT = ... | DictVal of (ide * evT) list
Dict(pairs) ->
if invariant pairs then DictVal(evalDictList pairs r)
else failwith("The Dictionary has multiple copy of the same key")|
AddPair(dict, newpair) ->
(match (eval dict r) with
DictVal (oldpairs) -> let evalnewpair = evalDictList newpair r in
if invariant (evalnewpair@oldpairs) then DictVal(oldpairs@evalnewpair)
else failwith ("A new key has the same value as another already inserted")|
_ -> failwith ("not a dictionary"))|
and evalDictList (pairs : (ide * exp) list) (r : evT env) : (ide * evT) list = match pairs with
[ ] -> [ ] |
(key,value) :: other -> (key, eval value r) :: evalDictList other r;;
和不变量:
and invariant (pairs : (ide * 'a) list) : bool = match pairs with
[ ] -> true |
(key,value) :: other -> if lookfor key other then invariant other else false
错误: 此表达式具有类型 (ide * evT) 列表,但预期的表达式类型为 (ide * exp) 列表类型 evT 与类型 exp 不兼容
在“Dict”不变量中使用 (ide * exp) 列表,而在“AddPair”不变量中将获得 evalnewpair@oldpairs,其中 evalnewpair 具有类型 (ide * evT) 和 oldpairs (ide * evT)。
解决方案
如果invariant
是相互递归函数定义的一部分,则需要明确使用通用量化:
and invariant: 'a. (ide * 'a) list -> bool = fun l -> ...
invariant
在您的情况下,从相互递归块中分离出来可能更简单。
推荐阅读
- node.js - 套接字 io 将数据插入表 Azure 移动应用 Node.js
- sql - 表值作为 SQL Server 存储过程的参数
- javascript - 增加计数器并动态更改依赖它的变量
- mysql - 获取最后 9 次出现
- javascript - 获取选定的数据表单分组集合选择
- sql-server - 如何将数据从一台服务器的视图复制到 SQL Server 数据库中另一台服务器的数据库表中?
- javascript - 调试为什么 react-native 发布版本会崩溃并调试一个工作正常
- react-native - 如何在本机反应中制作松鼠形状
- java - JsonMappingException:直接自引用导致循环(通过引用链:MyClass["underlyingValue"])
- rest - 如何获取可以对 DriveItem 资源执行的可能操作列表?