Want to pass the current Module to a Module Function
The goal is to reuse shared methods with other modules that only differ on t type
while keeping it restricted to specific t
of each module
type t
module parametricModule = CommonModule.make(<currentModule>)
include parametricModule
another option would be to pass only the type t
to the Module Function but it requires to something that carries t type
is it possible to pass pure types without params?
Can you show the code you tried? I’m not sure to follow.
There is a Module Function which has js bindings for HTML Canvas2D, it lists the common methods between Context2D and Path2D
the bindings for both Context2D and Path2D are exactly the same, they only differ on the t
receiver, so the Module Function gets a type t from the Module param with type ModuleWithT
Fragment of the common Module Function
module type ModuleWithT = {
type t
}
module MakeCanvasPath = (M: ModuleWithT) => {
// type t = M.t
/** https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc */
@send
external arc: (
M.t,
~x: float,
~y: float,
~r: float,
~a1: float,
~a2: float,
~ccw: bool=?,
unit,
) => unit = "arc"
/** https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arcTo */
@send
external arcTo: (M.t, ~x1: float, ~y1: float, ~x2: float, ~y2: float, ~r: float) => unit = "arcTo"
The on the consumer module, which will reuse those bindings, im forced to create a submodule, to pass the current type to the Module Function and include it’s content
module Path2DType = {
type t = t
}
// Here want to pass
include CanvasCommon.MakeCanvasPath(Path2DType)
The issue is that type t is aliased in submodule, want the t of the main module, without aliasing in submodule
can’t you just not alias the type t in your module function? playground link
module type WithTypeT = {
type t
}
module CanvasCommon = {
module MakeBindings = (M: WithTypeT) => {
@val external make: unit => M.t = "make"
@send external bar: M.t => string = "bar"
}
}
type t
module Path2DType = {
type t = t
}
include CanvasCommon.MakeBindings(Path2DType)
2 Likes
Another solution if you have multiple types t that share common behavior would be to have a parametric type t like this:
module CanvasCommon = {
type kind = [#Path2DType | #Other]
type t<'a>
module Bindings = {
@send external foo: t<[< kind]> => int = "foo"
@send external bar: t<[< kind]> => string = "bar"
}
}
module Path2DType = {
type t = CanvasCommon.t<[#Path2DType]>
@val external make: unit => t = "make"
include CanvasCommon.Bindings
}
let path2DType = Path2DType.make()
playground link
2 Likes