I am currently playing with modules to see how they can be used by similar Haskell class classes. I'm currently trying to play with a functor type class:
module type Functor =
sig
type 'a f
val fmap : ('a -> 'b) -> ('a f -> 'b f)
end
module IdFunc =
struct
type 'a f = Id of 'a
let fmap f = fun (Id a) -> Id (f a)
let runId (Id a) = a
end
let outmap (module F : Functor) av = F.fmap f av
However, in this case outmapit will not be typed correctly, the compiler will produce an error The type constructor F.f would escape its scope. I know why this error occurs in this case, but I'm not sure how to get around it (since the parameter f is parameterized).
I have already tried using locally abstract types:
let outmap (type s) (module F : Functor with type 'a f = s) f av = F.fmap f av
or
let outmap (type a) (type b) (type fa) (type fb)
(module F : Functor with type a f = fa type b f = fb) f av =
F.fmap f av
or
let outmap (type s) (module F : Functor with type f = s) f av = F.fmap f av
which just give me various syntax errors or input errors.
Is there any way around this?
In Haskell, it will be simple:
outmap : Functor f => (a -> b) -> f a -> f b
what would be equivalent in ocaml (if any)?
==== EDIT ====
I found one way to get something similar to work:
module type Functor =
sig
type a
type b
type af
type bf
val fmap : (a -> b) -> (af -> bf)
end
module type FromTo =
sig
type a
type b
end
module IdFunc =
functor (FT : FromTo) ->
struct
type a = FT.a
type b = FT.b
type 'a f = Id of 'a
type af = a f
type bf = b f
let fmap f = fun (Id a) -> Id (f a)
let runId (Id a) = a
end
let outmap (type a') (type b') (type af') (type bf')
(module F : Functor
with type a = a' and
type b = b' and
type af = af' and
type bf = bf')
f av = F.fmap f av
module M = IdFunc(struct type a = int type b = string end)
let oi = outmap (module M)
let test = oi (fun _ -> "Test") (M.Id 10)
-, , , .