From: "Raphael 'kena' Poss" <r.poss@uva.nl>
To: caml-list@inria.fr
Subject: [Caml-list] Polymorphic module type constraints
Date: Fri, 21 Mar 2014 08:31:22 +0100 [thread overview]
Message-ID: <DC1E40E6-C62A-47BB-9CFF-62B5E45195DB@uva.nl> (raw)
Hi all,
I am trying to take advantage of OCaml locally abstract types to constrain a functor. I want to use this to support the creation of modules from user-provided functions and some defaults. I encounter two issues with polymorphic types, which I am unable to solve. Maybe you will have some suggestions?
To show what I want, here is an example that "works fine" but uses regular types:
module type Eq = sig
type t
val (=) : t -> t -> bool
val (<>) : t -> t -> bool
end
let makeEq (type a) eq =
let module S = struct
type t = a
let (=) = eq
let (<>) x y = not (x = y)
end
in (module S : Eq with type t = a)
(* val eq1: int -> int -> bool *)
let eq1 a b = (a mod 3) = (b mod 3)
module Eq1 = (val makeEq eq1)
Here, I encounter the first issue:
(* val eq2: 'a option -> 'a option -> bool *)
let eq2 a b = match (a, b) with
| (None, None) -> true
| (Some x, Some y) -> x = y
| _ -> false
module Eq2 = (val makeEq ~eq2)
=>
Error: The type of this packed module contains variables:
(module Eq with type t = 'a option)
Is there any way to generalize?
Now, the other issue is when the signature explicitly declares a polymorphic type:
module type Poly = sig
type 'a t
end
module type Mappable = sig
type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
end
So far so good; but how to define makeMappable function, that takes a map function and Poly module and defines a Mappable instance from them?
My first try:
let makeMappable1 (type s) (module O : Poly with type t = s) map =
let module S : Mappable with type 'a t = 'a O.t = struct
include O
let map : ('a -> 'b) -> 'a t -> 'b t = map
end
in (module S)
=>
Error: In this `with' constraint, the new definition of t
does not match its original definition in the constrained signature:
Type declarations do not match: type t is not included in type 'a t
Ok, fair enough:
let makeMappable2 (type s) (module O : Poly with type 'a t = s) map =
let module S : Mappable with type 'a t = 'a O.t = ...
=>
Error: Syntax error: module-expr expected. (location: with type ... on first line)
So, I try to fix this with:
let makeMappable3 (module O : Poly) map =
let module S : Mappable with type 'a t = 'a O.t = struct
include O
let map : ('a -> 'b) -> 'a t -> 'b t = map
end
in (module S)
=>
Error: This expression has type ('a -> 'b) -> 'a O.t -> 'b t
but an expression was expected of type ('a -> 'b) -> 'a O.t -> 'b t
The type constructor O.t would escape its scope
Any suggestion as to how to define makeMappable?
Thanks in advance,
--
Raphael 'kena' Poss · r.poss@uva.nl
http://staff.science.uva.nl/~poss/
next reply other threads:[~2014-03-21 7:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-21 7:31 Raphael 'kena' Poss [this message]
2014-04-03 16:52 ` Leo White
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DC1E40E6-C62A-47BB-9CFF-62B5E45195DB@uva.nl \
--to=r.poss@uva.nl \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox