Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass a value to a functor in Ocaml?

Tags:

ocaml

I have a module signature for a Ring. IntRing (Z) was easy to define, but I want to create IntRingModP (Z_p). How can I pass P to the functor to set it when creating a module?

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;;

This results in File "polynomials.ml", line 25, characters 24-27: Error: Unbound module type Int

like image 529
Cole Gleason Avatar asked Jun 30 '15 04:06

Cole Gleason


2 Answers

Functors can only have modules as arguments. Hence, you need to make a new module type which 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 that helps.

like image 156
Aadit M Shah Avatar answered Nov 15 '22 10:11

Aadit M Shah


Before passing a module into a functor as a parameter you need to specify its signature. You're referring to a module type Int, but there is no such module type defined in OCaml by default. You need to define it yourself, like this:

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 instantiate it, you need to provide the value:

module Int2 = IntRingModP(struct let modulus = 2 end)
like image 37
ivg Avatar answered Nov 15 '22 12:11

ivg