Ocaml中“type ...and”和“let ...and”之间的范围不一致

Posted

技术标签:

【中文标题】Ocaml中“type ...and”和“let ...and”之间的范围不一致【英文标题】:Inconsistance of scoping between "type ...and " and "let ...and " in Ocaml 【发布时间】:2011-10-07 04:40:33 【问题描述】:

我想知道为什么在 Ocaml 中,“let.. and ...”与“type ... and ...”的范围不同:

下面的没问题,t2和t1在同一个作用域

# type t1 = t2 
and t2 = int;;

下面这个是错误的,v2 不在范围内

# let v1 = v2
and v2 = 3;;

  Characters 9-11:
  let v1 = v2
           ^^

Error: Unbound value v2

连“let rec”都不行……

# let rec v1 = v2
and v2 = 3;;

  Characters 13-15:
  let rec v1 = v2
               ^^
Error: This kind of expression is not allowed as right-hand side of `let rec'

为什么“type...and”和“let...and”之间的范围不一致?谢谢你。

【问题讨论】:

【参考方案1】:

类型是隐式递归的。如果你想和 "let" 有同样的效果,请使用 "let rec .. and"。

在理想的语言中,有意义的绑定形式应该有两个版本,一个是递归的,一个是非递归的。 Caml 中的let 就是这种情况,你有letlet rec。没有非递归类型绑定的可访问形式;它不必是默认值,即使type nonrec ... 也可以。这是 Caml 语法的缺陷;例如,in this blog post 给出了无法定义非递归类型的不良后果。

关于您的第二个示例,这与范围无关,而是某些递归定义的有效性,而不是其他定义。这是一个完全正交的问题(请参阅ocaml manual,其中递归定义是有效的),let rec 在这里完全按照您的要求进行,范围明确。

【讨论】:

类型是隐式的等递归。要获得 isorecursive 类型,您需要在编译器上使用 -rectypes 标志。这里感知到的不一致只是语法上的一个缺陷,并不值得为此而屈服。就像let... and... in... 结构一样,语言中不需要type nonrec... and... 结构。 @james:我认为你错了,-rectypes 启用等递归(名称与其展开之间的相等性),而标准代数数据类型是等递归(同构,由构造函数介导,名称之间及其展开)。但是,这与范围问题没有任何关系(此名称是否在范围内可用?)。关于nonrec 问题,您是否阅读过我链接到的博客文章,其中展示了强制递归类型定义引起的真正烦恼? 为子孙后代:type nonrec 现在是一件事。

以上是关于Ocaml中“type ...and”和“let ...and”之间的范围不一致的主要内容,如果未能解决你的问题,请参考以下文章

在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有啥副作用吗?

在 OCaml 中分隔多个“let”声明,后跟一个“let in”表达式

Lisp 的 let* 的 Ocaml 等价物?

用 let 重建 OCaml 模式

OCaml - 如何在匹配表达式中放置一个 let 绑定?

如何可选地提供 OCaml (let*) 运算符以与新旧编译器一起使用?