Functors take modules as arguments and return a module
Funcotrs require annotating arguments
Functors must start with a capital letter
module type X = {
let x: int
}
module type Y = {
let y: int
}
module MX = {
let x = 10
}
module MY = {
let y = 10
}
module type TXY = {
let xy: int
}
module F = (M1: X, M2: Y): TXY => {
let xy = M1.x + M2.y
}
module XY = F(MX, MY)
XY.xy->Js.log
module type POINT = {
type item
type t
let make: (item, item) => t
let getX: t => item
let getY: t => item
let add: (t, t) => t
let substract: (t, t) => t
}
module type ADD_SUB = {
type t
let add: (t, t) => t
let substract: (t, t) => t
}
module MakePoint = (MP: ADD_SUB): (POINT with type item := MP.t) => {
type item = MP.t
type t = (item, item)
let make = (x, y) => (x, y)
let getX = ((x, _)) => x
let getY = ((_, y)) => y
let add = ((x1, y1), (x2, y2)) => (MP.add(x1, x2), MP.add(y1, y2))
let substract = ((x1, y1), (x2, y2)) => (MP.substract(x1, x2), MP.substract(y1, y2))
}
module Int = {
type t = int
let add = (x: t, y: t) => x + y
let substract = (x: t, y: t) => x - y
}
module Float = {
type t = float
let add = (x: t, y: t) => x +. y
let substract = (x: t, y: t) => x -. y
}
module IntPoint = MakePoint(Int)
let ip1 = IntPoint.make(10, 10)
let ip2 = IntPoint.make(11, 11)
IntPoint.add(ip1, ip2)->Js.log
module FloatPoint = MakePoint(Float)
let ip1 = FloatPoint.make(10., 10.)
let ip2 = FloatPoint.make(11., 11.)
FloatPoint.add(ip1, ip2)->Js.log