Как исправить ошибку компиляции OCaml при использовании аннотаций типов с функторами?

/ (?:?! (& Л; / с \ ш) & л; [^ & л;] ) & л; / с \ ш * / г; - Удаляет любую последовательность в любой комбинации с

0
задан Joule 18 January 2019 в 08:57
поделиться

1 ответ

Основная проблема заключается в том, что ограничения вашей подписи делают полученный модуль слишком непрозрачным. Когда вы ограничиваете свой результат функтора:

 module FromToString (S:ToString) : Printable = ...

вы делаете тип t абстрактным типом, который может использоваться только функцией to_string и никогда не создается. Другими словами, модуль типа Printable сам по себе непригоден.

При запуске с функтором очень часто полезно посмотреть на тип модуля, выведенный компилятором для результирующего модуля. В случае FromToString это выглядит так:

module FromToString (S:ToString) : sig
  type t = S.t
  val print: t -> unit
end = ...

Вы можете видеть, что предполагаемый тип модуля результата

 sig
   type t = S.t
   val print: t -> unit
 end

очень похож на Printable за исключением того, что теперь тип t равен типу t модуля аргумента S.

Таким образом, можно повторно использовать Printable для записи полного типа модуля результата, добавив равенство типов с ограничением with:

  module FromToString (S:ToString): Printable with type t = S.t = struct
    type t = S.t
    let print a = print_string ( S.to_string a) 
  end

Появляется та же проблема для IntToString и может быть исправлена ​​аналогичным образом:

module IntToString : ToString with type t = int =
struct
    type t = int
    let to_string = string_of_int
end

Тогда ошибка компилятора исчезнет:

module PrintableInt = FromToString(IntToString)
let () = PrintableInt.print 3
0
ответ дан octachron 18 January 2019 в 08:57
поделиться