I’ve been trying to write an OCaml version the free selective functors examples from @snowleopard’s Selective Applicative Functors
paper and ran into problems when trying to write the ISA
example.
Briefly, I have implemented Free
as a functor, taking a module of effects Eff
:
module Selective = struct
module type S = sig
include Applicative.S
val select: ('a,'b) Either.t t -> ('a -> 'b) t -> 'b t
end
module Free = struct
module type S = sig
module Eff : sig
type 'a t
val map: 'a t -> f:('a -> 'b) -> 'b t
end
type _ t =
| Pure : 'a -> 'a t
| Select: ('a,'b) Either.t t * ('a -> 'b) Eff.t -> 'b t
include S with type 'a t := 'a t
val lift: 'a Eff.t -> 'a t
end
module Make(Eff: sig type 'a t ... end) : S with module Eff := Eff = struct
...
end
end
end
The example I am having problems with looks like this in Haskell:
type Program a = Select RW a
data RW a =
| Read Key (Value -> a)
| Write Key (Program Value) (Value -> a) deriving Functor
The key point here is that our effects RW
makes reference to Program
and vice versa.
I tried to use recursive modules to do this in OCaml:
module rec Program : Selective.Free.S with module Eff := Eff =
Selective.Free.Make(Eff)
and Eff : sig
type key = string
type value = string
type 'a t =
| Read of key * (value -> 'a)
| Write of key * (value Program.t) * (value -> 'a)
val map: 'a t -> f:('a -> 'b) -> 'b t
end = struct
...
end
But I get an error, Illegal recursive module reference
from the the mention of Eff
in the signature for Program
.
Is there any way to write this program in OCaml?