0

utop如果我在之后加载以下代码#require "mparser",它会在顶层被接受并在下面给出签名

open MParser

let infix p op = Infix (p |>> (fun _ a b -> (`Binop (op, a, b))), Assoc_left)

let operators =
  [
    [
      infix (char '*') `Mul;
      infix (char '/') `Div;
    ];
    [
      infix (char '+') `Add;
      infix (char '-') `Sub;
    ];
  ]

let decimal = many1_chars digit |>> int_of_string

let term = (decimal |>> fun i -> `Int i)
let expr s  =  expression operators term s

let rec calc = function
  | `Int i -> i
  | `Binop (op, a, b) ->
      match op with
        | `Add -> calc a + calc b
        | `Sub -> calc a - calc b
        | `Mul -> calc a * calc b
        | `Div -> calc a / calc b

接受utop

val infix :
  ('a, 'b) MParser.t ->
  'c -> ([> `Binop of 'c * 'd * 'd ] as 'd, 'b) MParser.operator = <fun>
val operators :
  (_[> `Binop of _[> `Add | `Div | `Mul | `Sub ] * 'a * 'a | `Int of int ]
   as 'a, unit)
  MParser.operator list list =
  [[Infix (<fun>, Assoc_left); Infix (<fun>, Assoc_left)];
   [Infix (<fun>, Assoc_left); Infix (<fun>, Assoc_left)]]
val decimal : (int, unit) MParser.t = <fun>
val term : ([> `Int of int ], unit) MParser.t = <fun>
val expr :
  unit MParser.state ->
  (_[> `Binop of _[> `Add | `Div | `Mul | `Sub ] * 'a * 'a | `Int of int ]
   as 'a, unit)
  MParser.reply = <fun>
val calc :
  ([< `Binop of [< `Add | `Div | `Mul | `Sub ] * 'a * 'a | `Int of int ] as 'a) ->
  int = <fun>

现在,如果我尝试加载dune utop包含此代码作为文件/模块的库,我收到以下错误:

~$ dune utop lib
      ocamlc lib/.lib.objs/lib__VariantExemple.{cmi,cmo,cmt} (exit 2)
(cd _build/default && /usr/local/bin/ocamlc.opt -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I lib/.lib.objs -I lib/.lib.objs/.private -I /Users/nrolland/.opam/system/lib/bytes -I /Users/nrolland/.opam/system/lib/mparser -I /Users/nrolland/.opam/system/lib/re -I /Users/nrolland/.opam/system/lib/re/perl -I /Users/nrolland/.opam/system/lib/seq -no-alias-deps -opaque -open Lib -o lib/.lib.objs/lib__VariantExemple.cmo -c -impl lib/variantExemple.ml)
File "lib/variantExemple.ml", line 5, characters 4-13:
Error: The type of this expression,
       (_[> `Binop of _[> `Add | `Div | `Mul | `Sub ] * 'a * 'a | `Int of int ]
        as 'a, '_weak1)
       operator list list, contains type variables that cannot be generalized

看起来缺少一些类型注释。我对多态变体类型不太熟悉,有没有明显的解决方案?

我希望将签名部分粘贴utop在界面中会起作用,但它似乎在.mli文件中无效

编辑:简单的解决方案是添加封闭类型注释。

let operators : ([ `Binop of [ `Add | `Div | `Mul | `Sub ] * 'a * 'a | `Int of int ] as 'a, unit) operator list list  =

我不确定是否有理由说明交互式会话和dune utop lib一次性加载的行为应该不同

4

1 回答 1

1

_的类型前面有,这表明你的类型是弱多态的,编译器拒绝让这些东西存在于编译对象中。

您可以使用 mwe 获得相同的结果:

let store = ref None

顶层是可以的,因为如果你评估类似的东西,它可以稍后解析为单态类型store:= Some1,它将类型“单态化”_a option refint option ref

于 2018-11-11T23:03:45.763 回答