SML的递归绑定似乎存在语法限制,我无法理解这些限制。在第二种情况下,我没有遇到这些限制(请参阅下面的源代码),在第一种情况下,我在使用自定义操作符时遇到了哪些限制?
下面是我遇到这个问题的例子。当我想使用自定义运算符时,它会失败,如注释中所解释的那样。在我正在测试SML源代码的主要SML实现中,只有保利/ML接受它为有效,而所有MLton、ML Kit和HaMLet都拒绝它。
错误信息让我很困惑。在我看来,最清楚的是来自HaMLet的那个,它抱怨“递归值绑定中的非法表达式”。
(* A datatype to pass recursion as result and to arguments. *)
datatype 'a process = Chain of ('a -> 'a process)
(* A controlling iterator, where the item handler is
* of type `'a -> 'a process`, so that while handling an item,
* it's also able to return the next handler to be used, making
* the handler less passive. *)
val rec iter =
fn process: int -> int process =>
fn first: int =>
fn last: int =>
let
val rec step =
fn (i: int, Chain process) (* -> unit *) =>
if i < first then ()
else if i = last then (process i; ())
else if i > last then ()
else
let val Chain process = process i
in step (i + 1, Chain process)
end
in step (first, Chain process)
end
(* An attempt to set‑up a syntax to make use of the `Chain` constructor,
* a bit more convenient and readable. *)
val chain: unit * ('a -> 'a process) -> 'a process =
fn (a, b) => (a; Chain b)
infixr 0 THEN
val op THEN = chain
(* A test of this syntax:
* - OK with Poly/ML, which displays “0-2|4-6|8-10|12-14|16-18|20”.
* - fails with MLton, which complains about a syntax error on line #44.
* - fails with ML Kit, which complains about a syntax error on line #51.
* - fails with HaMLet, which complains about a syntax error on line #45.
* The clearest (while not helpful to me) message comes from HaMLet, which
* says “illegal expression within recursive value binding”. *)
val rec process: int -> int process =
(fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process))))
val () = iter process 0 20
val () = print "\n"
(* Here is the same without the `THEN` operator. This one works with
* all of Poly/ML, MLton, ML Kit and HaMLet. *)
val rec process =
fn x =>
(print (Int.toString x);
Chain (fn x => (print "-";
Chain (fn x => (print (Int.toString x);
Chain (fn x => (print "|";
Chain process)))))))
val () = iter process 0 20
val () = print "\n"
(* SML implementations version notes:
* - MLton, is the last version, built just yesterday
* - Poly/ML is Poly/ML 5.5.2
* - ML Kit is MLKit 4.3.7
* - HaMLet is HaMLet 2.0.0 *)更新
我可以解决这个问题,但还是不明白。如果删除最外层的括号,那么它将验证:
val rec process: int -> int process =
fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process)))而不是:
val rec process: int -> int process =
(fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process))))但为什么会这样呢?SML语法的微妙性?它的理性是什么?
发布于 2014-09-16 06:32:15
这只是语言定义中一个限制性过强的句子,上面写着:
对于rec中的每个值绑定"pat = exp“,exp必须是"fn match”形式。
严格地说,这不允许任何括号。实际上,这很少是一个问题,因为您几乎总是使用fun声明语法。
https://stackoverflow.com/questions/25858856
复制相似问题