【问题标题】:OCaml: recursion with first-class modules and existential typeOCaml:具有一流模块和存在类型的递归
【发布时间】:2018-07-01 01:45:53
【问题描述】:

我正在尝试创建一个交替使用两个模块(相同类型)的函数,同时更深入地进行递归。我将模块作为参数传递,当我向模块添加存在类型时,一切都出错了。让我有点吃惊的是,如果我将函数设为非递归(就像我发现的所有远程相似的示例一样),它就可以工作。

这是我认为的最小示例(只是传递的单个模块):

module type TEST =
  sig
    type t
    val foo : t -> unit
  end

let rec foo
          (type a)
          (module Test : TEST with type t = a)
          (arg : a) : unit =
   (* Test.foo arg *) (* <- works *)
   (* I tried various type annotations, but none worked: *)
   foo (module Test : TEST with type t = a) (arg : a)

示例的错误消息:

Error: This expression has type
         (module TEST with type t = a) -> a -> 'b
       but an expression was expected of type 
         (module TEST with type t = a) -> a -> 'b
       The type constructor a would escape its scope

为什么它不起作用,我该怎么做才能使它起作用?

【问题讨论】:

    标签: recursion module ocaml existential-type first-class


    【解决方案1】:

    不确定是否完全理解您的错误,但是在进行递归时,通常最好将类型注释放在最高级别。 这是一个有效的版本:

    module type TEST =
    sig
      type t
      val foo : t -> unit
    end
    
    let rec foo : type a. (module TEST with type t = a) -> a -> unit
      = fun (module Test) arg ->
        if true
          then foo (module Test) arg 
          else Test.foo arg
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 2018-10-17
      • 1970-01-01
      • 2016-02-02
      相关资源
      最近更新 更多