Если я загружаю следующий код в 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
однократная загрузка должны вести себя по-разному