Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast the type in functors OCaml

Tags:

functor

ocaml

I've get the follow code about the functors in OCaml:

type comparison = Less | Equal | Greater;;

module type ORDERED_TYPE =
    sig
        type t
        val compare: t -> t -> comparison
    end
;;

module Set =
    functor (Elt: ORDERED_TYPE) ->
        struct
            type element = Elt.t
            type set = element list
            let empty = []
            let rec add x s =
                match s with
                | [] -> [x]
                | hd :: tl ->
                    match Elt.compare x hd with
                    | Equal -> s
                    | Less -> x :: s
                    | Greater -> hd :: add x tl
            let rec member x s =
                match s with
                | [] -> false
                | hd :: tl ->
                    match Elt.compare x hd with
                    | Equal -> true
                    | Less -> false
                    | Greater -> member x tl
    end
;;

module OrderedString : ORDERED_TYPE = 
    struct
        type t = string
        let compare x y =
            if x = y then Equal
            else if x < y then Less
            else Greater
    end
;;

module StringSet = Set(OrderedString);;

let out = StringSet.member "foo" (StringSet.add "foo" StringSet.empty);; (*compile error, where "foo" is expected OrderedString.t but actually is string*)

The above error can be avoided by eliminating the : ORDERED_TYPE in module OrderedString : ORDERED_TYPE =

Just can't understand why.

Analogously, if there is any type in a module like

module A = struct type t = string end;;

How can I specify a string value as the type A.t but not an actual string

Thanks.

like image 461
yjasrc Avatar asked Dec 06 '25 19:12

yjasrc


2 Answers

You can look at how it is done in the standard library : set.mli. The signature of the functor is

module Make (Ord : OrderedType) : S with type elt = Ord.t

the with type elt = Ord.t part indicates that the elt type is not abstract.

like image 84
Thomash Avatar answered Dec 09 '25 22:12

Thomash


As mentioned by Tomash, you're lacking a type constraint, but not in the functor signature (there isn't any in your code in fact), but in the argument you're giving to it. Basically, when you write

module OrderedString : ORDERED_TYPE = struct ... end

the definition of the type t in OrderedString will be abstracted away, since t is an abstract type in the ORDERED_TYPE signature. What you want here is to say that OrderedString is indeed an implementation of ORDERED_TYPE, but with a known type t. This is exactly what you'll get with

module OrderedString: ORDERED_TYPE with type t = string = struct ... end
like image 45
Virgile Avatar answered Dec 09 '25 23:12

Virgile