Используйте абстрактный модуль как часть определения типа отдельно от модуля - PullRequest
0 голосов
/ 30 ноября 2019

Я пытаюсь использовать тип модуля Partial_information, который создается через функтор Make_partial_information, в качестве типа поля contents в типе Cell.t. Однако я получаю сообщение об ошибке Unbound module Partial_information.

open Core

(* module which is used as argument to functor *)
module type Partial_type = sig
  type t
  val merge : old:t -> new_:t -> t
end

(* type of result from functor *)
module type Partial_information = sig
  type a
  type t = a option
  val merge : old:t -> new_:t -> t
  val is_nothing : t -> bool
end

(* The functor *)
module Make_partial_information(Wrapping : Partial_type):
  (Partial_information with type a = Wrapping.t)
= struct
  type a = Wrapping.t
  type t = a option

  let merge ~(old : t) ~(new_ : t) =
    match (old, new_) with
    | (None, None) -> None
    | (None, Some a) -> Some a
    | (Some a, None) -> Some a
    | (Some a, Some b) -> (Wrapping.merge ~old:a ~new_:b) |> Some

  let is_nothing (it: t) : bool = (is_none it)
end

(* Checking to make sure understanding of functor is correct *)
module Int_partial_type = struct
  type t = int
  let merge ~old ~new_ = new_ [@@warning "-27"]
end

module Int_partial_information = Make_partial_information(Int_partial_type)

(* Trying to use _any_ type which might have been created by the functor as a field in the record *)
module Cell = struct
  type id = { name : string ; modifier : int }
  type t = {
    (* Error is here stating `Unbound module Partial_information` *)
    contents : Partial_information.t ;
    id : id
  }
end

1 Ответ

0 голосов
/ 01 декабря 2019

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

module Cell(P : Partial_information) = struct
  type id = { name : string ; modifier : int }
  type partial
  type t = {
    contents : P.t;
    id : id
  }
end

Или еще проще сделать тип ячейки полиморфным:

  type 'a cell = {
    contents : 'a;
    id : id
  }

, так какСам по себе тип не особенно интересен и не зависит от типа содержимого.

PS: можно использовать модули первого класса и GADT для количественного определения конкретной реализации типа модуля. Но неясно, стоит ли взрывать ваш бюджет сложности здесь:

type 'a partial_information = (module Partial_information with type a = 'a)
module Cell = struct
  type id = { name : string ; modifier : int }
  type t = E: {
    contents : 'a ;
    partial_information_implementation: 'a partial_information;
    id : id
  } -> t
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...