I have a module in OCaml that is parameterized by another module, which represents a data structure (H = Hashtable, M = Map, L = LossyMap). I would now like to let this data structure be selected via the command line.
The way I create the main processing module is:
module HashSampler = MakeSampler(HashtableMatrix)
module MapSampler = MakeSampler(MapMatrix)
etc.
Unfortunately, the code that multiplexes between these is ugly:
match representation with
| "Hashtable" ->
let matrix = HashSampler.create () in
HashSampler.process_file matrix file
| "Map" ->
let matrix = MapSampler.create () in
MapSampler.process_file matrix file
Is there a better way of doing this that somehow prevents code duplication?
You can use first class modules. Here's some example code that shows one possibility.
module type Sampler = sig
type t
val create : unit -> t
val process_file : t -> string -> unit
end
module HashSampler : Sampler = struct
type t = unit
let create () = ()
let process_file () file = ()
end
module MapSampler : Sampler = struct
type t = unit
let create () = ()
let process_file () file = ()
end
let choose_sampler : string -> (module Sampler) = function
| "Hashtable" -> (module HashSampler)
| "Map" -> (module MapSampler)
let process representation file =
let (module M) = choose_sampler representation in
let matrix = M.create () in M.process_file matrix file
Related
I try to understand a strange behaviour of some functions of a module that rely on a variable of this module masked by the signature of this module. I would like to print this variable at some points of the program, but since it is masked, I do not known how to access it.
Moreover, this module is part of a big project that I do not want to modify and recompile myself.
Is it possible to access this variable for debugging purposes ? Even doing temporarily dirty things ?
EDIT: here some representative code
module type S = sig val f : unit -> unit end
module M : S = struct let x = ref 0 let f () = Format.printf "%d#." !x; incr x end
How to access M.x ?
Of course you can!
First, you can just hide the signature for a while :
module type S = sig val f : unit -> unit end
module M (* : S *) = struct
let x = ref 0
let f () = Format.printf "%d#." !x; incr x
end
Or you can show x in the signature :
module type S = sig
val x : int ref
val f : unit -> unit
end
module M : S = struct
let x = ref 0
let f () = Format.printf "%d#." !x; incr x
end
As you prefer. In both cases, M.x will be available outside the module.
You can even define a function print_x like this :
module type S = sig
val print_x : unit -> unit
val f : unit -> unit
end
module M : S = struct
let x = ref 0
let print_x () = Format.printf "%d#." !x
let f () = Format.printf "%d#." !x; incr x
end
and use M.print_x () wherever you want.
I have problems defining the type of a module that is returned by a functor. Could anyone solve this?
module type ANIMALTYPE = sig
val age : unit -> int
end
module type SHIPGENERATOR = sig
val age : unit -> int
(* Another possibility: include ANIMALTYPE *)
val hello : string
end
module RabbitModule : ANIMALTYPE = struct
let age () = 10
end
module Make_ShipGenerator (A : ANIMALTYPE) = struct
let age = A.age
let hello = "world"
end
let get_shipgenerator race = match race with
| Rabbit -> let module M = (Make_ShipGenerator (RabbitModule))
in (module M : SHIPGENERATOR)
Edit: Added hello to Make_ShipGenerator.
Edit 2: Added module type SHIPGENERATOR, which will include those parts needed from ANIMALTYPE.
Well, it is ANIMALTYPE, what else?
let module M = (Make_ShipGenerator (RabbitModule))
in (module M : ANIMALTYPE);;
I would like to make my code generic over strings and arrays (any indexable type really) using the following signature:
module type Indexable = sig
type 'a t
val get : int -> 'a t -> 'a
end
module MyCode (I : Indexable) = struct ... end
But of course I cannot apply my signature to strings as follows:
module StrMyCode = MyCode(struct
type 'a t = string
let get i a = a.[i]
end)
Is there any way to fix this issue? Or perhaps a different aprroach? I know I can use arrays of characters in the worst case but I'd rather save my code from ugly casts and this is something that was on my mind before so I'd like to get a clear answer for this.
GADT can be used with the functorized approach:
module type Indexable = sig
type 'a t
val get: int -> 'a t -> 'a
end
module MyCode(I:Indexable) = struct
let head x = I.get 0 x
end
Arrays can of course be made Indexable trivially:
module IndexableArray = struct
type 'a t = 'a array
let get i x = x.(i)
end
For string, you can just use a GADT with a single constructor. Note however, that you have to put some type annotation for get in order to force the polymorphic type (otherwise, the inferred type is int -> char t -> char):
module IndexableString = struct
type 'a t = String: string -> char t
let of_string s = String s
let get: type a. int -> a t -> a =
fun i s -> match s with String s -> s.[i]
end
Here is something I made using GADTs. I'm just wrapping my head around them, so there may be something a little wrong here. But it seems to work as far as I can see (with OCaml 4):
type _ indexable =
| A : 'a array -> 'a indexable
| C : string -> char indexable
let index (type s) (x: s indexable) i : s =
match x with
| A a -> a.(i)
| C s -> s.[i]
let main () =
let x = A [| 1; 2 |] in
let y = C "abc" in
Printf.printf "%d\n" (index x 0);
Printf.printf "%c\n" (index y 1)
If I load into the toplevel, I get this:
val index : 'a indexable -> int -> 'a = <fun>
val main : unit -> unit = <fun>
# main ();;
1
b
- : unit = ()
#
This might not be as general as what you're looking for.
If you declare the element type of the indexable as a separate type, you can do something like this:
module type Indexable = sig
type t
type elt
val get : int -> t -> elt
end
module IndexableString : Indexable = struct
type t = string
type elt = char
let get i a = a.[i]
end
module MyCode (I : Indexable) = struct
(* My code implementation *)
end
module StrMyCode = MyCode(IndexableString)
For arrays, you can do more or less the same:
module ArrayIndexable = struct
type elt = char
type t = char array
let get i a = a.(i)
end
Now, if you wish to retain some flexibility with arrays, you may change the above into a functor:
module ArrayIndexable (E : sig type e end) : Indexable with type elt = E.e =
struct
type elt = e
type t = elt array
let get i a = a.(i)
end
It is more verbose than the polymorphic version you are looking for, but it let you encode both "indexable" types uniformly.
I am doing composition of automata. So at the end of that, I want to draw the composed automata also. So are there any libraries for that in ocaml? or are there ocaml wrappers written for any graph visualization tool? I have googled for it but didn't get much for ocaml. Any comments on ocamlgraph? I will get more than 100 states in composed automata.
Use ocamlgraph -- it is a graph library that can generate a dot/graphviz file for you but can also do a lot of other stuff that maybe interesting for handling your automata.
The library can do fixpoints, spanning trees, graph search, find strongly connected components, etc., etc.
Here is a complete example of some directed graph with labeled edges + module for doing depth-first-search + module for creating dot-representations of it:
(* representation of a node -- must be hashable *)
module Node = struct
type t = int
let compare = Pervasives.compare
let hash = Hashtbl.hash
let equal = (=)
end
(* representation of an edge -- must be comparable *)
module Edge = struct
type t = string
let compare = Pervasives.compare
let equal = (=)
let default = ""
end
(* a functional/persistent graph *)
module G = Graph.Persistent.Digraph.ConcreteBidirectionalLabeled(Node)(Edge)
(* more modules available, e.g. graph traversal with depth-first-search *)
module D = Graph.Traverse.Dfs(G)
(* module for creating dot-files *)
module Dot = Graph.Graphviz.Dot(struct
include G (* use the graph module from above *)
let edge_attributes (a, e, b) = [`Label e; `Color 4711]
let default_edge_attributes _ = []
let get_subgraph _ = None
let vertex_attributes _ = [`Shape `Box]
let vertex_name v = string_of_int v
let default_vertex_attributes _ = []
let graph_attributes _ = []
end)
with that you can write your program; e.g. something like this:
(* work with the graph ... *)
let _ =
let g = G.empty in
let g = G.add_edge_e ...
...
let file = open_out_bin "mygraph.dot" in
let () = Dot.output_graph file g in
...
if D.has_cycle g then ... else ...
I would just write automata as text to file (in format suitable for graphviz) and then run graphviz against that file.
The aim of the module described below is to implement a module which once initiated by an integer n does all the operations based on the value of n.
module ReturnSetZero =
functor ( Elt : int ) ->
struct
let rec sublist b e l =
match l with
[] -> failwith "sublist"
| h :: t ->
let tail = if e = 0 then [] else sublist (b - 1) (e - 1) t in
if b > 0 then tail else h :: tail
let rec zerol = 0:: zerol
let zeron = sublist 0 n zerol
(*other operations based on n which is selected once when the module is initialized*)
end;;
Error: Unbound module type int
What is the issue here? Is there an alternate implementation which is more effective/intuitive?
A functor maps modules to modules. An integer is not a module, so you cannot use it to as a functor parameter.
You need to define a module type:
module type WITH_INTEGER = sig
val integer : int
end
module PrintInteger =
functor (Int:WITH_INTEGER) -> struct
let print_my_integer () = print_int Int.integer
end
Of course, unless your module needs to expose types that are dependent on the value of the integer (or you have to expose a lot of values dependent on that integer), you're probably better off with a plain function that takes that integer as an argument:
let my_function integer =
let data = complex_precomputations integer in
function arg -> do_something_with arg data
This lets you run the complex pre-computations only once on the integer (when you pass it to the function).