Can I pass a value to a functor in Ocaml?
I have a module signature for Ring. IntRing (Z) is easy to define, but I want to create IntRingModP (Z_p). How do I pass P to a functor to be set when the module is created?
module IntRing : Ring = struct
type t = int
let zero = 0
let one = 1
let add a b = a+b
let mult a b = a*b
let compare = compare
let equal a b = (a=b)
let to_string = Int.to_string
let print a = print_string (to_string a)
end;;
module IntRingModP (P : Int) : Ring = struct
let p = P
type t = int
let zero = 0 mod p
let one = 1 mod p
let add a b = (a+b) mod p
let mult a b = (a*b) mod p
let compare a b = compare (a mod p) (b mod p)
let equal a b = ((a mod p) = (b mod p))
let to_string a = Int.to_string (a mod p)
let print a = print_string (to_string a)
end;;
The result is File "polynomials.ml", line 25, characters 24-27:
Error: Unbound module type Int
source to share
Functors can only take modules as arguments. Hence, you need to create a new module type that wraps int
:
module type IntT = sig val x : int end;; module IntRingModP (P : IntT) : Ring = struct let p = P.x type t = int let zero = 0 mod p let one = 1 mod p let add a b = (a+b) mod p let mult a b = (a*b) mod p let compare a b = compare (a mod p) (b mod p) let equal a b = ((a mod p) = (b mod p)) let to_string a = Int.to_string (a mod p) let print a = print_string (to_string a) end;;
Hope it helps.
source to share
Before passing a module to a functor as a parameter, you need to specify its signature. You mean the module type Int
, but by default this module type is not specified in OCaml. You have to define it yourself, for example:
module type Modulus = sig
val modulus : int
end
module IntRingModP (P : Modulus) : Ring = struct
let p = P.modulus
type t = int
let zero = 0 mod p
let one = 1 mod p
let add a b = (a+b) mod p
let mult a b = (a*b) mod p
let compare a b = compare (a mod p) (b mod p)
let equal a b = ((a mod p) = (b mod p))
let to_string a = Int.to_string (a mod p)
let print a = print_string (to_string a)
end
And to create it you need to provide a value:
module Int2 = IntRingModP(struct let modulus = 2 end)
source to share