I am new to OCaml and I am trying to convert some Haskell code to OCaml.
I have the following code, where I explore the OCaml module system and functors.
module type F =
sig
type 'a f
val fmap : ('a -> 'b) -> 'a f -> 'b f
end
module type FOO =
functor (C : F) ->
sig
type f
end
module Foo : FOO =
functor (C : F) ->
struct
type f = { foo : 'x . 'x C.f -> 'x ;
bar : 'x . 'x C.f -> 'x C.f }
end
module List =
struct
include List
type 'a f = 'a list
let fmap = List.map
end
module Bar =
struct
include Foo (List)
let ea = { foo = List.hd ; bar = List.tl }
end
I keep having the error Unbound record field foo.
The fact that Foo is a functor complicates matters, I feel like I cannot provide an annotation as I want to.
What am I missing?
The problem arises because you're saying that Foo has the signature of FOO, and in FOO you're saying that f is abstract, i.e. that its definition is hidden. From the compiler's perspective you've deliberately hidden the implementation details of Foo.f.
There are several way you can fix this:
FOO from Foo, allowing it to be inferred instead.module Foo =
functor (C : F) ->
struct
type f = { foo : 'x . 'x C.f -> 'x ;
bar : 'x . 'x C.f -> 'x C.f }
end
will infer its type as
module Foo :
functor (C : F) ->
sig type f = { foo : 'x. 'x C.f -> 'x; bar : 'x. 'x C.f -> 'x C.f; } end
f in FOO.module type FOO =
functor (C : F) ->
sig
type f = { foo : 'x . 'x C.f -> 'x ;
bar : 'x . 'x C.f -> 'x C.f }
end
Foo and FOO that allow you to create values of type f without needing to know the exact details of its implementation. In this case this is however made more difficult by OCaml's lack of higher rank polymorphism, meaning you can't pass the universally quantified foo and bar functions to the constructor function directly (see Section 5.3 in the OCaml manual). The workaround is to wrap these functions in a record (or object), which effectively just brings us back to solution 2.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With