【问题标题】:OCaml Compilation Type Error, not the right expected type of the functionOCaml 编译类型错误,不是正确的预期函数类型
【发布时间】:2019-10-30 03:51:01
【问题描述】:

这里是 OCaml 的新手。

基本上试图用两个函数编译一段代码,但我无法编译它,第 9 行,第 26-27 列字符出现类型错误,说:

"错误:此表达式的类型为 t,但表达式应为类型 字符串""

基本上,第 8 行调用的解析函数期待类型字符串,但我不知道为什么。

sexp 参数的类型:

type sexp = Atom of string | List of sexp list

代码:

open Sexplib.Sexp

let rec parse_bindings bindings =
  match bindings with
    | [] -> []
    | first::rest ->
      match first with
        | List([Atom(name); e]) ->
          [(name, parse e)] @ (parse_bindings rest)

let rec parse sexp : expr =
  match sexp with
    | Atom(s) ->
      (* some code *)
    | List(sexps) ->
      match sexps with
        | (* some code *)
        | [Atom("let"); List(bindings_sexp); e2] ->
          let binding_expr = parse_bindings bindings in
            ELet(binding_expr, parse e2)
        | _ -> failwith "foo"

【问题讨论】:

  • 你应该发布一个独立的小例子。由于(* some code *) 和缺少定义,此代码无法编译。如果人们可以自己尝试您的代码,那么提供帮助会容易得多。

标签: ocaml


【解决方案1】:

您提供的代码不会编译,因为在第 9 行引用了 parse,但直到稍后才定义。

要定义两个相互递归的函数,您需要使用let rec ... and ...

let rec f x = (* definition of f, which calls g *)
and g x = (* definition of g, which calls f *)

由于parse 的后续定义在第 9 行不可见,因此该名称必须引用某个先前的定义。也许在Sexp 模块中定义了一个名为parse 的函数。 (这是谨慎使用open 的原因之一。)

【讨论】:

  • 谢谢!有用。一个问题,我如何将第 9 行使用的解析指定为该文件中的一个函数。在其他语言中,通常有一个类似命名空间的东西来避免命名冲突。
  • 没有简单的方法来引用当前模块。惯用的解决方案(恕我直言)是删除open Sexplib.Sexp。如果使用完整的模块名称过于繁琐,您可以改用一个短名称:module S = Sexplib.Sexp。然后您可以使用S.Atom 等形式的名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
相关资源
最近更新 更多