Ocaml:以模块类型实现功能

问题描述 投票:0回答:1

我有以下模块类型:

module type Element = sig
  type t
  type mystruct = {x: int; y: int}
  val (<) : t -> t -> bool
  val string_of_element : t -> string
  (* val (>) : t -> t -> bool = not (<) *)
end

如您所见,我希望类型

t
是通用的,但我希望
mystruct
具有特定的结构。问题是,当我创建一个模块
MyInteger
时,“实现”模块
Element
如下:

module MyInteger = struct
  type t = int
  let (<) a b = a < b
  let string_of_element = string_of_int
end

它抱怨

“mystruct”类型是必需的,但未提供

除非我在这个模块中重新定义类型 mystruct,否则它不起作用。

我不明白为什么它不使用我在模块类型中定义的类型?有什么办法可以让它做到这一点吗?

与函数 (>) 相同,如何让 Ocaml 考虑 (>) 与 (<) whatever it is?

) 相反
ocaml functor
1个回答
0
投票

模块类型为规格。它们不实现任何东西,既不实现函数也不实现类型。 当你写模块类型时

module type Element = sig
  ...
  type mystruct = {x: int; y: int}
  ...
end

您指定每个实现都必须定义自己的

mystruct
变体,这确实不是很有用。 解决方案很可能是将共享类型定义移到模块类型规范之外:

type mystruct = {x:int; y:int}
module type Element = sig ... end

如果

mystruct
类型对
Element
模块类型规范中的其他类型有一定的依赖性,一个好的解决方案是使共享类型定义多态于依赖于实现的部分:

type 'a mystruct = { x:'a; y:int }
module type Element = struct
  ...
  type t
  type mystruct_elt = t mystruct
  ...
end

同样,可以使用高阶函数来定义派生函数

let make_gt (<) x y = y < x
module I = struct
  let (<) = ...
  let (>) = make_gt (<)
end

如果有多个派生函数,您可以使用函子来扩展基本模块实现:

module Extend(X:Base_element) = struct
  let (>) x y = X.( y < x )
  ...
end
module Full = struct
  module Core = struct ... end
  include Core
  include Extend(Core)
end
© www.soinside.com 2019 - 2024. All rights reserved.