You can not define a generic type type 'a t = {value : 'a}
with the condition that the type variable 'a
is showable. When you define such a generic type you quantify over all types, but what you want is a bounded quantification: for all type 'a
such that 'a
is showable…
By the way, we can do something close from what you want using functor (but you’ll have to instantiate the right module in each case).
module type Show = sig
type t
val show : t -> string
end
let show (type a) (module S : Show with type t = a) = S.show
module Show_int = struct
type t = int
let show = string_of_int
end
type 'a value = {value : 'a}
Now, you can define a functor saying : if I can show a value of type a
then I can show a value of type a value
:
module Show_value (S : Show) = struct
type t = S.t value
let show {value} = Printf.sprintf "{value = %s}" (S.show value)
end
and now:
let c = {value = {value = 1}}
(* you have to instantiate the functor with the right parameter *)
show (module Show_value (Show_value (Show_int))) c;;
- : string = "{value = {value = 1}}"
With modular implicit, the solution would be simpler but there is still a lot of work before having this in the language (as explain in this comment).
module type Show = sig type t val show : t -> string end
let show {S : Show} = S.show;;
val show : {S : Show} -> S.t -> string = <fun>
implicit module Show_int = struct type t = int let show = string_of_int end
implicit module Show_value {S : Show} = struct
type t = S.t value
let show {value} = Printf.sprintf "{value = %s}" (S.show value)
end
let c = {value = {value = 1}}
(* here with implicit, the module is inferred by the compiler *)
show c;;
- : string = "{value = {value = 1}}"