Ensure same results from multiple calls to a ref - module

I call a function in a module to generate unique labels, eg.
MyMod.gensym
defined as
let gensym : string -> string =
let c = ref 0 in
fun s -> incr c; Printf.sprintf "!%s%d" s (!c)
But, I want to be able to get reproducible results at certain times from functions that use this gensym, eg.
let reproducible = SomeMod.call x
may return ["!a1"; "!a2"] the first time and ["!a3"; ...] the second
How can I ensure reproducible output in this case (eg. force ref to start from the same value), but without needing to change the implementation of gensym in its module?

You could add an optional argument to reset it:
let gensym : ?reset:bool -> string -> string =
let c = ref 0 in
fun ?(reset=false) s ->
if reset then
c := 1
else
incr c;
Printf.sprintf "!%s%d" s (!c)

Related

How to create a set of elements without knowing the type of the element?

I'm running into problems around recursive/mutually referential module definitions trying to use Caml's Map/Set stuff. I really want ones that just work on types, not modules. I feel like it should be possible to do this with first-class modules, but I'm failing to make the syntax work.
The signature I want is:
module type NonFunctorSet = sig
type 'a t
val create : ('a -> 'a -> int) -> 'a t
val add : 'a t -> 'a -> 'a t
val remove : 'a t -> 'a -> 'a t
val elements : 'a t -> 'a list
end
Possibly with other Caml.Set functions included. My idea for how this would work is something like:
type 'a t = {
m : (module Caml.Set.S with type elt = 'a);
set : m.t
}
let create (compare : 'a -> 'a -> t) =
module m = Caml.Set.Make(struct type t = 'a let compare = compare end) in
let set = m.empty in
{m = m; set = set;}
end
But that doesn't work for a number of reasons; 'a isn't exposed in the right places, I can't reference m.t in the same record where m was defined, etc.
Is there a version of this that works?
Adding more context about my use case:
I have two modules, Region and Tribe. Tribe needs access to a lot of the interface of Region, so I am currently creating Tribe as a functor, MakeTribe(Region : RegionT). Region mostly doesn't need to know about Tribe, but it does need to be able to store a mutable collection of Tribe.t that represent the tribes living in that region.
So, somehow or other, I need a RegionT like
module type RegionT = sig
type <region>
val get_local_tribes : <region> -> <tribes>
val add_tribe : <region> -> <tribe> -> unit
...
end
I don't really care about the specific syntax of <tribe>, <tribes> and <region> in this, so long as the fully built Tribe module can know that Region.get_local_tribes, etc, will yield an actual Tribe.t
The circular dependency problem is that the type <tribe> does not exist until the module Tribe is created. My idea so far has been to have RegionT.t actually be 'a RegionT.t, and then Tribe could simply refer to Tribe.t Region.t. This is all fine if I'm satisfied with keeping a <tribe> list inside Region, but I want it to be a set.
I feel this should be possible based on the following example code :
module Example : sig
type t
val compare : t -> t -> int
end = struct
type t = int
let compare = Int.compare
end
module ExampleSet = Caml.Set.Make(struct type t = Example.t let compare = Example.compare end)
All that Example exposes in its interface is a type and a function from two instances of that type to an int; why is that more than having a 'a -> 'a -> int, which has the same things?
Using Polymoprhic Sets and Maps from the Base Library
In Base and Core libraries, from Jane Street, ordered data structures, such as maps, sets, hash tables, and hash sets, are all implemented as polymorphic data structures, instead of functorized versions as in the vanilla OCaml standard library.
You can read about them more in the Real World OCaml Maps and Hashtbales chapter. But here are quick recipes. When you see a comparator in the function interface, e.g., in Map.empty what it actually wants you is to give you a module that implements the comparator interface. The good news is that most of the modules in Base/Core are implementing it, so you don't have to worry or know anything about this to use it, e.g.,
# open Base;;
# let empty = Map.empty (module Int);;
val empty : (Base.Int.t, 'a, Base.Int.comparator_witness) Base.Map.t =
<abstr>
# Map.add empty 1 "one";;
- : (Base.Int.t, string, Base.Int.comparator_witness) Base.Map.t
Base.Map.Or_duplicate.t
= `Ok <abstr>
So the simple rule, if you want a set,map,hashtable,hashset where the key element has type foo, just pass (module Foo) as a comparator.
Now, what if you want to make a mapping from your custom type? E.g., a pair of ints that you would like to compare in lexicographical order.
First of all, we need to define sexp_of and compare functions. For our type. We will use ppx derivers for it, but it is easy to make it manually if you need.
module Pair = struct
type t = int * int [##deriving compare, sexp_of]
end
Now, to create a comparator, we just need to use the Base.Comparator.Make functor, e.g.,
module Lexicographical_order = struct
include Pair
include Base.Comparator.Make(Pair)
end
So now we can do,
# let empty = Set.empty (module Lexicographical_order);;
val empty :
(Lexicographical_order.t, Lexicographical_order.comparator_witness)
Base.Set.t = <abstr>
# Set.add empty (1,2);;
- : (Lexicographical_order.t, Lexicographical_order.comparator_witness)
Base.Set.t
= <abstr>
Despite that Base's data structures are polymorphic they strictly require that the module that provides the comparator is instantiated and known. You can just use the compare function to create a polymorphic data structure because Base will instantiate a witness type for each defined compare function and capture it in the data structure type to enable binary methods. Anyway, it is a complex issue, read on for easier (and harder) solutions.
Instantiating Sets on mutually dependent modules
In fact, OCaml supports mutually recursive funtors and although I would suggest you to break the recursion by introducing a common abstraction on which both Region and Tribe depend, you can still encode your problem in OCaml, e.g.,
module rec Tribe : sig
type t
val create : string -> t
val compare : t -> t -> int
val regions : t -> Region.t list
end = struct
type t = string * Region.t list
let create name = name,[]
let compare (x,_) (y,_) = String.compare x y
let regions (_,r) = r
end
and Region : sig
type t
val empty : t
val add_tribe : Tribe.t -> t -> t
val tribes : t -> Tribe.t list
end = struct
module Tribes = Set.Make(Tribe)
type t = Tribes.t
let empty = Tribes.empty
let add_tribe = Tribes.add
let tribes = Tribes.elements
end
Breaking the Dependency Loop
A much better solution would be to redesign your modules and break the dependency loop. The simplest approach would be just to choose some identifier that will be used to compare tribes, e.g., by their unique names,
module Region : sig
type 'a t
val empty : 'a t
val add_tribe : string -> 'a -> 'a t -> 'a t
val tribes : 'a t -> 'a list
end = struct
module Tribes = Map.Make(String)
type 'a t = 'a Tribes.t
let empty = Tribes.empty
let add_tribe = Tribes.add
let tribes r = Tribes.bindings r |> List.map snd
end
module Tribe : sig
type t
val create : string -> t
val name : t -> string
val regions : t -> t Region.t list
val conquer : t Region.t -> t -> t Region.t
end = struct
type t = Tribe of string * t Region.t list
let create name = Tribe (name,[])
let name (Tribe (name,_)) = name
let regions (Tribe (_,r)) = r
let conquer region tribe =
Region.add_tribe (name tribe) tribe region
end
There are also tons of other options and in general, when you have mutual dependencies it is actually an indicator of a problem in your design. So, I would still revisit the design stage and eschew the circular dependencies.
Creating Polymorphic Sets using the Vanilla OCaml Standard Library
It is not an easy task, especially if you need to handle operations that involve several sets, e.g., Set.union. The problem is that Set.Make is generating a new type for the set per each compare function so when we need to union two sets it is hard for us to prove to the OCaml compiler that they were created from the same type. It is possible but really painful, I am showing how to do this only to discourage you from doing this (and to showcase OCaml's dynamic typing capabilities).
First of all we need a witness type that will reify an OCaml type for the set into a concrete value.
type _ witness = ..
module type Witness = sig
type t
type _ witness += Id : t witness
end
Now we can define our polymorphic set as an existential that holds the set itself and the module with operations. It also holds the tid (for type identifier) that we will later use to recover the type 's of the set.
type 'a set = Set : {
set : 's;
ops : (module Set.S with type elt = 'a and type t = 's);
tid : (module Witness with type t = 's);
} -> 'a set
Now we can write the create function that will take the compare function and turn it into a set,
let create : type a s. (a -> a -> int) -> a set =
fun compare ->
let module S = Set.Make(struct
type t = a
let compare = compare
end) in
let module W = struct
type t = S.t
type _ witness += Id : t witness
end in
Set {
set = S.empty;
ops = (module S);
tid = (module W);
}
The caveat here is that each call to create will generate a new instance of the set type 's so we can compare/union/etc two sets that were created with the same create function. In other words, all sets in our implementation shall share the same ancestor. But before that lets take a pain and implement at least two operations, add and union,
let add : type a. a -> a set -> a set =
fun elt (Set {set; tid; ops=(module Set)}) -> Set {
set = Set.add elt set;
ops = (module Set);
tid;
}
let union : type a. a set -> a set -> a set =
fun (Set {set=s1; tid=(module W1); ops=(module Set)})
(Set {set=s2; tid=(module W2)}) ->
match W1.Id with
| W2.Id -> Set {
set = Set.union s1 s2;
tid = (module W1);
ops = (module Set);
}
| _ -> failwith "sets are potentially using different types"
Now, we can play with it a bit,
# let empty = create compare;;
val empty : '_weak1 set = Set {set = <poly>; ops = <module>; tid = <module>}
# let x1 = add 1 empty;;
val x1 : int set = Set {set = <poly>; ops = <module>; tid = <module>}
# let x2 = add 2 empty;;
val x2 : int set = Set {set = <poly>; ops = <module>; tid = <module>}
# let x3 = union x1 x2;;
val x3 : int set = Set {set = <poly>; ops = <module>; tid = <module>}
# let x4 = create compare;;
val x4 : '_weak2 set = Set {set = <poly>; ops = <module>; tid = <module>}
# union x3 x4;;
Exception: Failure "sets are potentially using different types".
#

The signature for this packaged module couldn't be inferred in recursive function

I'm still trying to figure out how to split code when using mirage and it's myriad of first class modules.
I've put everything I need in a big ugly Context module, to avoid having to pass ten modules to all my functions, one is pain enough.
I have a function to receive commands over tcp :
let recvCmds (type a) (module Ctx : Context with type chan = a) nodeid chan = ...
After hours of trial and errors, I figured out that I needed to add (type a) and the "explicit" type chan = a to make it work. Looks ugly, but it compiles.
But if I want to make that function recursive :
let rec recvCmds (type a) (module Ctx : Context with type chan = a) nodeid chan =
Ctx.readMsg chan >>= fun res ->
... more stuff ...
|> OtherModule.getStorageForId (module Ctx)
... more stuff ...
recvCmds (module Ctx) nodeid chan
I pass the module twice, the first time no problem but
I get an error on the recursion line :
The signature for this packaged module couldn't be inferred.
and if I try to specify the signature I get
This expression has type a but an expression was expected of type 'a
The type constructor a would escape its scope
And it seems like I can't use the whole (type chan = a) thing.
If someone could explain what is going on, and ideally a way to work around it, it'd be great.
I could just use a while of course, but I'd rather finally understand these damn modules. Thanks !
The pratical answer is that recursive functions should universally quantify their locally abstract types with let rec f: type a. .... = fun ... .
More precisely, your example can be simplified to
module type T = sig type t end
let rec f (type a) (m: (module T with type t = a)) = f m
which yield the same error as yours:
Error: This expression has type (module T with type t = a)
but an expression was expected of type 'a
The type constructor a would escape its scope
This error can be fixed with an explicit forall quantification: this can be done with
the short-hand notation (for universally quantified locally abstract type):
let rec f: type a. (module T with type t = a) -> 'never = fun m -> f m
The reason behind this behavior is that locally abstract type should not escape
the scope of the function that introduced them. For instance, this code
let ext_store = ref None
let store x = ext_store := Some x
let f (type a) (x:a) = store x
should visibly fail because it tries to store a value of type a, which is a non-sensical type outside of the body of f.
By consequence, values with a locally abstract type can only be used by polymorphic function. For instance, this example
let id x = x
let f (x:a) : a = id x
is fine because id x works for any x.
The problem with a function like
let rec f (type a) (m: (module T with type t = a)) = f m
is then that the type of f is not yet generalized inside its body, because type generalization in ML happens at let definition. The fix is therefore to explicitly tell to the compiler that f is polymorphic in its argument:
let rec f: 'a. (module T with type t = 'a) -> 'never =
fun (type a) (m:(module T with type t = a)) -> f m
Here, 'a. ... is an universal quantification that should read forall 'a. ....
This first line tells to the compiler that the function f is polymorphic in its first argument, whereas the second line explicitly introduces the locally abstract type a to refine the packed module type. Splitting these two declarations is quite verbose, thus the shorthand notation combines both:
let rec f: type a. (module T with type t = a) -> 'never = fun m -> f m

Getting syntax error in ocaml

I am trying to make a module that would allow to create a table in ocaml. It would do a query called project to limit the table's values. However on the last line of the definition of the function chooser I am getting syntax error.
module type TABLE =
sig
type database
type table
val create_table: string list * string list* (string list) list -> table
val printTable : table -> string
val listToString : string list -> string
val project : string list * table -> table
val chooser : string list * string list-> string list
end;;
module UsingTable : TABLE =
struct
type table = (string list * string list* (string list) list)
type database = table list
let create_table (a,b,c) = (a,b,c)
let chooser inputList = (
for i = 0 to (List.length trueFalseList-1) do
if List.nth trueFalseList i = "True"
then
(List.nth inputList i)::ans
done
List.rev ans;;)
let project (conditions, aTable)= (
let rec innerProc tmp= function
n,[],v->List.rev tmp
|n,cH::cT,v-> if List.mem cH conditions
then innerProc (["True"]::tmp) (n,cT,v)
else innerProc (["False"]::tmp) (n,cT,v)
in
let trueFalseList = innerProc [] aTable
let rec finalListCreator = match aTable with
n,[],[]->n,[],[]
|n,cH::cT,[]->n,chooser cH ::finalListCreator cT,[]
|n,c,h::t -> n,c,chooser h ::finalListCreator t
)
let rec listToString aList = match aList with
[] -> ""
| h::t -> "\t"^h^"\t"^listToString t
let rec printTable aTable = match aTable with
[],[],[] -> ""
| [],[],vH::vT -> "\n"^(listToString vH)^printTable ([],[],vT)
| [],cH::cT,v -> "\t"^cH^"\t"^printTable([],cT, v)
| n, c , v-> "\n"^(List.hd n)^"\n\n"^printTable([],c, v)
end;;
let atable =UsingTable.create_table (["Student"], ["Id";"Name";"Gender";"Course"],
[["001";"Jim";"M";"AlgoDS"];
["002";"Linnea";"F";"Databases"];
["003";"Anna";"F";"C#"];
["004";"Abby";"F";"C#"];
["005";"Arthur";"M";"JavaScript"]]);;
print_string (UsingTable.printTable atable) ;;
These lines have at least two syntax problems:
let chooser inputList = (
for i = 0 to (List.length trueFalseList-1) do
if List.nth trueFalseList i = "True"
then
(List.nth inputList i)::ans
done
List.rev ans;;)
First, the for .. done is one expression, and List.rev ans is another expression. You need a semicolon (;) between them.
Second, you should use ;; only when you want the input up to that point to be processed. But here if you process the input at the ;; you are missing a right parenthesis.
In my opinion, you should be entering ;; only at the toplevel. The best way to think of this token is as an instruction to the toplevel. It's not part of normal OCaml syntax.
These are only the first two errors. There are quite a few other errors in the code. It might be good to add one function at a time to the module so you can concentrate on a few problems at a time.
Update
The environment you're using is a little bit extra complicated because it has an Evaluate button that asks to evaluate what you've typed so far. This makes the ;; token much less useful.
It would be a good discipline to use this environment without using the ;; token at all. Just click the Evaluate button when you want an evaluation.
The main trick is if you want to evaluate a statement (a unit-valued expression in OCaml) at the outer level, like say Printf.printf "hello world\n". The usual idiom to avoid putting ;; before this is to make it into a declaration like so:
let () = Printf.printf "hello world\n"
That is the one non-obvious idiom that people use when writing source code (where the ;; almost never appears in my experience).

expose a private type for module extension in OCaml

I'd like to extend a module but I need access to its private components. Here's an example:
nat.mli:
type t
val zero : t
val succ : t -> t
nat.ml:
type t = int
let zero = 0
let succ x = x + 1
I'd like to define a new module Ext_nat that defines a double function. I was trying to do something like this.
ext_nat.mli:
include (module type of Nat)
val double : t -> t
ext_nat.ml:
include Nat
let double x = 2 * x
It's not working as I don't have access to the representation of x in the last line.
Now that I'm thinking about this, it may not be such a good idea anyway because this would break the encapsulation of nat. So what is the best way to do this? I could define a new module nat_public where type t = int in the signature, and define nat and ext_nat with a private type t. What do you think?
You need to use with type statement. It is possible to write the code below in many different ways, but the idea is always the same.
module type NatSig =
sig
type t
val zero : t
val succ : t -> t
end
module type ExtNatSig =
sig
include NatSig
val double : t -> t
end
module ExtNat : ExtNatSig =
struct
type t = int
let zero = 0
let succ = fun x -> x + 1
let double = fun x -> x * 2
end
module Nat = (ExtNat : NatSig with type t = ExtNat.t)
let z = Nat.zero
let _ = ExtNat.double z
The problem is that as far as I remember it's impossible to achieve this behavior with your file structure: you define your module implicitly with signature in .mli file and structure itself in .ml, so you don't have enough control over you module, that's why I suggest you to reorganize your code a little bit (if it's not a problem).

Iteration in Mutable State

I would like to write a function that accepts a function which performs an operation on the elements of a list, and accepts the list as an argument as well. I am trying to practice with anonymous functions and iterate through a list without using the built in iter in OCaml.
I also wrote a test case which should pass when this function is completed. I am struggling to figure out how to do this, as I want to perform an operation on each element without returning anything, rather updating the list by this iterative operation.
This is how I have started and would like to maintain this format:
Any suggestions? Any help would be greatly appreciated.
let rec iteration (f: 'h -> unit) (l: 'h list) : unit =
let test () : bool =
let list = [1; 2; 3] in
iteration (fun r -> r * 2) list;
list = [2; 4; 6]
;; run_test "iteration" test