Currently I'm trying to use Batteries with ppx_deriving.show or something similar.
I am wondering how to use them together usefully.
To create dumping functions, I feel ppx_deriving.show is useful.
But I have a little bit troubles using them together like the followings.
open Batteries
type t = { a: (int,int) Map.t }
[##deriving show]
Now Map.pp is not defined, so it can't be compiled.
My adhoc fix is that I create module Map which include Batteries.Map and define function pp.
open Batteries
module Map = struct
include Map
let pp f g fmt t = ... (* create dump function by man hand *)
end
type t = { a: (int,int) Map.t }
[##deriving show]
It works, but it is painful for me to adapt all of data structures...
Core with ppx_deriving.sexp is an alternative choice, but I prefer Batteries with ppx_deriving.show.
Does anybody know how to solve the problem?
Your fix is the right way. If you want to use deriving for data types M.t declared without [##deriving], you have to give its methods such as M.pp for show by yourself:
module M = struct
include M
let pp = ... (* code for pretty-printing M.t *)
end
There is a way to partially automate this:
module M = struct
include M
type t = M.t = ... (* the same type definition of M.t *)
[##deriving show]
end
It generates M.pp for type t using deriving.
With ppx_import, you can avoid copy-and-pasting of the definition:
module M = struct
include M
type t = [%import: M.t]
[##deriving show]
end
This should be expanded to the former code.
As you have found out, deriving show of Map.t is not really useful though: normally you do not want to see the binary tree representation of Map.t unless you are debugging Map module itself.
Related
I want to use the Stack module from the Stdlib of OCaml, but I also need a membership function, which the Stack module lacks. So, following https://dev.realworldocaml.org/files-modules-and-programs.html, I created a file stack1.ml reading:
include Stack
let mem a t = List.mem a t.c
since c is the name of the record used in stack.ml (that file contains the line: type 'a t = { mutable c : 'a list; mutable len : int; }). But I get:
Error: Unbound record field c
What can I do ?
(And also: do I need a file with a different name Stack1 ? This is a bit annoying for the files calling it.)
The fact that the type 'a Stack.t is implemented using a mutable list or any other data type is an implementation detail that is abstracted away by the interface of the Stack module.
In other words, outside of the Stack module, you can only use the functions provided by the stack module that works on the abstract type 'a Stack.t independently of this implementation.
Fortunately, those functions are more than enough to implement a mem function. For instance, with a fold:
let mem x s = Stack.fold (fun acc y -> acc || x = y) false s
I have a functor to make a Heap module from a Comparable module, and a polymorphic function to apply Prim's algorithm to graphs with arbitrary labels. Ideally I'd like to be able to write something like:
let prim (graph: 'a graph)=
let module EdgeHeap=Heap.Make(
struct
type t='a edge
...
end
) in
...
let heap=EdgeHeap.create () in
...
but ocamlc says that 'a is unbound. How do I work around this?
Normally, you'd have prim (along with related functions) in a functor of its own that is parameterized over a graph module signature. I.e. something like:
module type GraphSpec = sig
type t
...
end
module GraphAlgorithms(G: GraphSpec) = struct
type graph = ...
module EdgeHeap = Heap.Make(struct
type t = G.t edge
...
end)
let prim (g: graph) = ...
let kruskal (g: graph) = ...
end
This avoids the use of type variables; instead, you pass the type through the GraphSpec functor argument.
But if you just need it for a single function, this may be overkill. You can work around it then by using locally abstract types. A simple example to illustrate how that works:
let min_list (type u) (l: u list) =
let module S = Set.Make(struct
type t = u
let compare = compare
end) in
S.of_list l |> S.min_elt
I am using ocaml_plugin to write calculator which is able to evaluate OCaml expressions at run time.
This is my plugin interface.
open Ocaml_plugin.Std
module type S = sig
val f : unit -> float
end
let univ_constr : (module S) Ocaml_dynloader.Univ_constr.t =
Ocaml_dynloader.Univ_constr.create ()
I am able to load functions with the signature unit -> float, for example,
let f () = 3.14159
let f () = 1.5 *. 1.5 *. 3.
and call f () in the main program to evaluate the expression in the function body. However, it supports float type only.
What should I do if I want it to support int? Time.t? Or any arbitrary OCaml type in Pervasive?
let f () = List.length [1;2;3] (* int *)
let f () = Time.now () (* Time.t *)
let f () = "hello world!!!" (* string *)
In order to evaluate at run time, ocaml_plugin seems to be the only way to go. However, in order to let the loader/compiler know what is loaded dynamically, I have to write an interface. How should I change the interface file so that it supports other types?
GADT (Generalized Algebraic Data Type) to rescue.
Although GADT exists for a long time, it is a relatively new topic in OCaml. It helps a lot in writing generic libraries in OCaml safely.
module Value = struct
type 'a t
module Packed = struct
type 'a unpacked = 'a t
type t = T : 'a unpacked -> t
end
end
Value.Packed.t is a packed data type that we want. Theotically any data type 'a can be packed.
I would like to represent some scalar value (e.g. integers or strings)
by either it's real value or by some NA value and later store them
in a collection (e.g. a list). The purpose is to handle missing values.
To do this, I have implemented a signature
module type Scalar = sig
type t
type v = Value of t | NA
end
Now I have some polymorphic Vector type in mind that contains Scalars. Basically, some of the following
module Make_vector(S: Scalar) = struct
type t = S.v list
... rest of the functor ...
end
However, I cannot get this to work. I would like to do something like
module Int_vector = Make_vector(
struct
type t = int
end
)
module Str_vector = Make_vector(
struct
type t = string
end
)
... and so on for some types.
I have not yet worked a lot with OCaml so maybe this is not the right way. Any advises on how to realize such a polymorphic Scalar with a sum type?
The compiler always responds with the following message:
The parameter cannot be eliminated in the result type.
Please bind the argument to a module identifier.
Before, I have tried to implement Scalar as a sum type but ran into
complexity issues when realizing some features due to huge match clauses. Another (imo not so nice) option would be to use option. Is this a better strategy?
As far as I can see, you are structuring v as an input type to your functor, but you really want it to be an output type. Then when you apply the functor, you supply only the type t but not v. My suggestion is to move the definition of v into your implementation of Make_vector.
What are you trying to do exactly with modules / functors? Why simple 'a option list is not good enough? You can have functions operating on it, e.g.
let rec count_missing ?acc:(acc=0) = function
| None::tail -> count_missing ~acc:(acc+1) tail
| _::tail -> count_missing ~acc tail
| [] -> acc ;;
val count_missing : ?acc:int -> 'a option list -> int = <fun>
count_missing [None; Some 1; None; Some 2] ;;
- : int = 2
count_missing [Some "foo"; None; Some "bar"] ;;
- : int = 1
I have an ocaml type :
type t = A | B | ...
and a function to print things about that type :
let pp_t fmt x = match x with
| A -> Format.fprintf fmt "some nice explanations about A"
| B -> Format.fprintf fmt "some nice explanations about B"
| ...
How could I write a function to print all the explanations ? Something equivalent to :
let pp_all_t fmt =
Format.fprintf fmt A;
Format.fprintf fmt B;
...
but that would warn me if I forget to add a new constructor.
It would be even better to have something that automatically build that function,
because my problem is that t is quiet big and changes a lot.
I can't imagine how I can "iterate" on the type constructors, but maybe there is a trick...
EDIT: What I finally did is :
type t = A | B | ... | Z
let first_t = A
let next_t = function A -> B | B -> C | ... | Z -> raise Not_found
let pp_all_t fmt =
let rec pp x = pp_t fmt x ; try let x = next_t x in pp x with Not_found -> ()
in pp first_t
so when I update t, the compiler warns me that I have to update pp_t and next_t, and pp_all_t doesn't have to change.
Thanks to you all for the advices.
To solve your problem for a complicated and evolving type, in practice I would probably write an OCaml program that generates the code from a file containing a list of the values and the associated information.
However, if you had a function incr_t : t -> t that incremented a value of type t, and if you let the first and last values of t stay fixed, you could write the following:
let pp_all_t fmt =
let rec loop v =
pp_t fmt v;
if v < Last_t then loop (incr_t v)
in
loop First_t
You can't have a general polymorphic incr_t in OCaml, because it only makes sense for types whose constructors are nullary (take no values). But you can write your own incr_t for any given type.
This kind of thing is handled quite nicely in Haskell. Basically, the compiler will write some number of functions for you when the definitions are pretty obvious. There is a similar project for OCaml called deriving. I've never used it, but it does seem to handle the problem of enumerating values.
Since you say you want a "trick", if you don't mind using the unsafe part of OCaml (which I personally do mind), you can write incr_t as follows:
let incr_t (v: t) : t =
(* Please don't use this trick in real code :-) ! See discussion below.
*)
if t < Last_t then
Obj.magic (Obj.magic v + 1)
else
failwith "incr_t: argument out of range"
I try to avoid this kind of code if at all possible, it's too dangerous. For example, it will produce nonsense values if the type t gets constructors that take values. Really it's "an accident waiting to happen".
One needs some form of metaprogramming for such tasks. E.g. you could explore deriving to generate incr_t from the Jeffrey's answer.
Here is a sample code for the similar task : https://stackoverflow.com/a/1781918/118799
The simplest thing you can do is to define a list of all the constructors:
let constructors_t = [A; B; ...]
let pp_all_t = List.iter pp_t constructors_t
This is a one-liner, simple to do. Granted, it's slightly redundant (which gray or dark magic would avoid), but it's still probably the best way to go in term of "does what I want" / "has painful side effects" ratio.