为什么口译员告诉我 "This kind of expression is not allowed as right-hand side of `let rec'"
why the interpreter tell me "This kind of expression is not allowed as right-hand side of `let rec'"
我编写了一个 ocaml 程序,通过解析器组合器解析算术表达式。
type 'a parser = char list -> ('a * (char list)) list
let return (x: 'a): 'a parser = fun input -> [x, input]
let fail: 'a parser = fun _ -> []
let ( >>= ) (p: 'a parser) (f : 'a -> 'b parser): 'b parser =
fun input -> List.map (fun (x, i) -> f x i) (p input) |> List.flatten
let ( ||| ) (p: 'a parser) (q: 'a parser) =
fun input -> (p input) @ (q input)
let token: (char parser) = function
| x::xs -> [x, xs]
| [] -> []
let char(c: char): (char parser) =
token >>= fun x ->
if x = c then return x else fail
let digit: (char parser) =
token >>= fun x ->
if x >= '0' && x <= '9' then return x else fail
let rec many(p: 'a parser): 'a list parser =
(p >>= fun x ->
many p >>= fun xs ->
(return (x::xs)))
||| (return [])
let number =
many digit >>= fun x ->
return (List.fold_left (fun l r -> l * 10 + (int_of_char r - int_of_char '0')) 0 x)
type expr = Add of (expr * expr)
| Sub of (expr * expr)
| Mul of (expr * expr)
| Div of (expr * expr)
| Neg of expr
上面的代码运行良好。
let rec expression: expr parser =
term >>= fun l ->
(char '+' ||| char '-') >>= fun op ->
term >>= fun r ->
if op = '+' then return (Add (l, r)) else return (Sub (l, r))
and term: expr parser =
factor >>= fun l ->
(char '*' ||| char '/') >>= fun op ->
factor >>= fun r ->
if op = '*' then return (Mul (l, r)) else return (Div (l, r))
and factor: expr parser =
expression
||| (char '(' >>= fun _ ->
expression >>= fun e ->
char ')' >>= fun _ ->
return e)
||| (char '-' >>= fun _ ->
factor >>= fun e ->
return (Neg e))
但是这段代码有错误
Error: This kind of expression is not allowed as right-hand side of `let rec'
本页(link)说:
"the compiler only allows three possible constructs to show up on the righthand side of a let rec: a function definition, a constructor, or the lazy keyword."
我认为类型解析器是一个函数而不是一个值,为什么会这样?
"Function definition" 表示文字 fun x ->
结构。函数式语言考虑部分函数应用程序,例如
factor >>= fun l -> ...
redexes,而不是文字值,这意味着当它们出现在简单变量绑定的 RHS 上时,严格的语言必须立即对其求值,例如
term = factor >>= fun l -> ...
由于通常急于计算递归定义的 RHS 会产生无限循环,因此严格的语言通常要么禁止该构造,要么要求将绑定显式标记为惰性。
右边应该"function definition"不只是一个函数。函数定义是手册form fun ->
or function ...
, including syntactic sugar for let f x ...
. A more correct wording is in sections 6.7.1 and 7.3的句法结构。
我编写了一个 ocaml 程序,通过解析器组合器解析算术表达式。
type 'a parser = char list -> ('a * (char list)) list
let return (x: 'a): 'a parser = fun input -> [x, input]
let fail: 'a parser = fun _ -> []
let ( >>= ) (p: 'a parser) (f : 'a -> 'b parser): 'b parser =
fun input -> List.map (fun (x, i) -> f x i) (p input) |> List.flatten
let ( ||| ) (p: 'a parser) (q: 'a parser) =
fun input -> (p input) @ (q input)
let token: (char parser) = function
| x::xs -> [x, xs]
| [] -> []
let char(c: char): (char parser) =
token >>= fun x ->
if x = c then return x else fail
let digit: (char parser) =
token >>= fun x ->
if x >= '0' && x <= '9' then return x else fail
let rec many(p: 'a parser): 'a list parser =
(p >>= fun x ->
many p >>= fun xs ->
(return (x::xs)))
||| (return [])
let number =
many digit >>= fun x ->
return (List.fold_left (fun l r -> l * 10 + (int_of_char r - int_of_char '0')) 0 x)
type expr = Add of (expr * expr)
| Sub of (expr * expr)
| Mul of (expr * expr)
| Div of (expr * expr)
| Neg of expr
上面的代码运行良好。
let rec expression: expr parser =
term >>= fun l ->
(char '+' ||| char '-') >>= fun op ->
term >>= fun r ->
if op = '+' then return (Add (l, r)) else return (Sub (l, r))
and term: expr parser =
factor >>= fun l ->
(char '*' ||| char '/') >>= fun op ->
factor >>= fun r ->
if op = '*' then return (Mul (l, r)) else return (Div (l, r))
and factor: expr parser =
expression
||| (char '(' >>= fun _ ->
expression >>= fun e ->
char ')' >>= fun _ ->
return e)
||| (char '-' >>= fun _ ->
factor >>= fun e ->
return (Neg e))
但是这段代码有错误
Error: This kind of expression is not allowed as right-hand side of `let rec'
本页(link)说: "the compiler only allows three possible constructs to show up on the righthand side of a let rec: a function definition, a constructor, or the lazy keyword."
我认为类型解析器是一个函数而不是一个值,为什么会这样?
"Function definition" 表示文字 fun x ->
结构。函数式语言考虑部分函数应用程序,例如
factor >>= fun l -> ...
redexes,而不是文字值,这意味着当它们出现在简单变量绑定的 RHS 上时,严格的语言必须立即对其求值,例如
term = factor >>= fun l -> ...
由于通常急于计算递归定义的 RHS 会产生无限循环,因此严格的语言通常要么禁止该构造,要么要求将绑定显式标记为惰性。
右边应该"function definition"不只是一个函数。函数定义是手册form fun ->
or function ...
, including syntactic sugar for let f x ...
. A more correct wording is in sections 6.7.1 and 7.3的句法结构。