caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* type aliases and recursive modules
@ 2007-05-15 15:40 Josh Berdine
  2007-05-15 16:29 ` [Caml-list] " Philippe Wang
  0 siblings, 1 reply; 5+ messages in thread
From: Josh Berdine @ 2007-05-15 15:40 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 920 bytes --]

Hi,

 

There's something I'm not understanding about recursive modules.  Consider
the following distilled example:

 

# 

module rec A : sig

  type t = It of ASet.t

  val compare : t -> t -> int

  val get : t -> ASet.t

end = struct

  type t = It of ASet.t

  let compare = compare

  let get = function It(x) -> x

end

 

and ASet : sig

  type t

  val get_its_elements : t -> A.t list

end = struct

  module C = Set.Make(A)

  type t = C.t

  let get_its_elements x = C.elements (A.get x)

end

;;

Characters 350-359:

    let get_its_elements x = C.elements (A.get x)

                                        ^^^^^^^^^

This expression has type ASet.t but is here used with type

  C.t = Set.Make(A).t

#

 

Why doesn't the typechecker know that ASet.t and C.t are the same type?
Anyone know a workaround?

 

This is with the 3.10.0 beta version, but seems to be the same back to 3.07.

 

Cheers,  Josh


[-- Attachment #2: Type: text/html, Size: 5825 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] type aliases and recursive modules
  2007-05-15 15:40 type aliases and recursive modules Josh Berdine
@ 2007-05-15 16:29 ` Philippe Wang
  2007-05-15 16:56   ` Josh Berdine
  0 siblings, 1 reply; 5+ messages in thread
From: Philippe Wang @ 2007-05-15 16:29 UTC (permalink / raw)
  To: Josh Berdine, ocaml ml

Josh Berdine wrote:
>
> Hi,
>
> There’s something I’m not understanding about recursive modules. 
> Consider the following distilled example:
>
> #
>
> module rec A : sig
>
> type t = It of ASet.t
>
> val compare : t -> t -> int
>
> val get : t -> ASet.t
>
> end = struct
>
> type t = It of ASet.t
>
> let compare = compare
>
> let get = function It(x) -> x
>
> end
>
> and ASet : sig
>
> type t
>
> val get_its_elements : t -> A.t list
>
> end = struct
>
> module C = Set.Make(A)
>
> type t = C.t
>
> let get_its_elements x = C.elements (A.get x)
>
> end
>
> ;;
>
> Characters 350-359:
>
> let get_its_elements x = C.elements (A.get x)
>
> ^^^^^^^^^
>
> This expression has type ASet.t but is here used with type
>
> C.t = Set.Make(A).t
>
> #
>
> Why doesn’t the typechecker know that ASet.t and C.t are the same 
> type? Anyone know a workaround?
>
> This is with the 3.10.0 beta version, but seems to be the same back to 
> 3.07.
>
> Cheers, Josh
>

Hi,

There is an incoherency in your definition of ASet.get_its_elements.

In the signature of ASet, get_its_elements take an argument of type 
ASet.t, but then in its definition, it takes an argument of type A.t (as 
A.get takes an argument of type A.t, and you give ASet.get_its_elements' 
argument to A.get)

--
Philippe Wang
mail@philippewang.info


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [Caml-list] type aliases and recursive modules
  2007-05-15 16:29 ` [Caml-list] " Philippe Wang
@ 2007-05-15 16:56   ` Josh Berdine
  2007-05-15 17:11     ` Philippe Wang
  2007-05-15 17:40     ` Andreas Rossberg
  0 siblings, 2 replies; 5+ messages in thread
From: Josh Berdine @ 2007-05-15 16:56 UTC (permalink / raw)
  To: 'ocaml ml'

[-- Attachment #1: Type: text/plain, Size: 1647 bytes --]

Hi,

 

Josh Berdine wrote:

> 

> Hi,

> 

> There's something I'm not understanding about recursive modules. 

> Consider the following distilled example:

> 

 

      [snip buggy simplification]

 

> 

> Why doesn't the typechecker know that ASet.t and C.t are the same 

> type? Anyone know a workaround?

> 

> This is with the 3.10.0 beta version, but seems to be the same back to 

> 3.07.

> 

> Cheers, Josh

> 

 

Hi,

 

There is an incoherency in your definition of ASet.get_its_elements.

 

In the signature of ASet, get_its_elements take an argument of type 

ASet.t, but then in its definition, it takes an argument of type A.t (as 

A.get takes an argument of type A.t, and you give ASet.get_its_elements' 

argument to A.get)

 

--

Philippe Wang

mail@philippewang.info

 

 

Thanks Philippe and Christopher, yes, mea culpa, I forgot, e.g., a call to
choose.  But my confusion remains:

 

 

# 

module rec A : sig

  type t = It of ASet.t

  val compare : t -> t -> int

  val get : t -> ASet.t

end = struct

  type t = It of ASet.t

  let compare = compare

  let get = function It(x) -> x

end

 

and ASet : sig

  type t

  val get_its_elements : t -> A.t list

end = struct

  module C = Set.Make(A)

  type t = C.t

  let get_its_elements x = C.elements (A.get (C.choose x))

end

;;

                                      Characters 350-370:

    let get_its_elements x = C.elements (A.get (C.choose x))

                                        ^^^^^^^^^^^^^^^^^^^^

This expression has type ASet.t but is here used with type

  C.t = Set.Make(A).t

#

 

 

Am I still doing something stupid?

 

Cheers,  Josh


[-- Attachment #2: Type: text/html, Size: 8842 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] type aliases and recursive modules
  2007-05-15 16:56   ` Josh Berdine
@ 2007-05-15 17:11     ` Philippe Wang
  2007-05-15 17:40     ` Andreas Rossberg
  1 sibling, 0 replies; 5+ messages in thread
From: Philippe Wang @ 2007-05-15 17:11 UTC (permalink / raw)
  To: Josh Berdine, ocaml ml

Josh Berdine wrote:
>
> Thanks Philippe and Christopher, yes, mea culpa, I forgot, e.g., a 
> call to choose.  But my confusion remains:
>
>  
>
> #
>
> module rec A : sig
>
>   type t = It of ASet.t
>
>   val compare : t -> t -> int
>
>   val get : t -> ASet.t
>
> end = struct
>
>   type t = It of ASet.t
>
>   let compare = compare
>
>   let get = function It(x) -> x
>
> end
>
>  
>
> and ASet : sig
>
>   type t
>
>   val get_its_elements : t -> A.t list
>
> end = struct
>
>   module C = Set.Make(A)
>
>   type t = C.t
>
>   let get_its_elements x = C.elements (A.get (C.choose x))
>
> end
>
> ;;
>
>                                       Characters 350-370:
>
>     let get_its_elements x = C.elements (A.get (C.choose x))
>
>                                         ^^^^^^^^^^^^^^^^^^^^
>
> This expression has type ASet.t but is here used with type
>
>   C.t = Set.Make(A).t
>
> #
>
>  
>
>  
>
> Am I still doing something stupid?
>
>  
>
> Cheers,  Josh
>
Hi,

Your A.get function takes something of the form "It of something", which 
is of type A.t = It of ASet.t.
There is no such a constructor (It) in,
let get_its_elements x = C.elements (A.get (C.choose x))
So it can't go right when you call A.get...
;-)

Cheers,
--
  Philippe Wang
  mail@philippewang.info


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] type aliases and recursive modules
  2007-05-15 16:56   ` Josh Berdine
  2007-05-15 17:11     ` Philippe Wang
@ 2007-05-15 17:40     ` Andreas Rossberg
  1 sibling, 0 replies; 5+ messages in thread
From: Andreas Rossberg @ 2007-05-15 17:40 UTC (permalink / raw)
  To: Josh Berdine, 'ocaml ml'

"Josh Berdine" <berdine@dcs.qmul.ac.uk>:
> #
> module rec A : sig
>  type t = It of ASet.t
>  val compare : t -> t -> int
>  val get : t -> ASet.t
> end = struct
>  type t = It of ASet.t
>  let compare = compare
>  let get = function It(x) -> x
> end
>
> and ASet : sig
>  type t
>  val get_its_elements : t -> A.t list
> end = struct
>  module C = Set.Make(A)
>  type t = C.t
>  let get_its_elements x = C.elements (A.get (C.choose x))
> end
>
>                                      Characters 350-370:
>    let get_its_elements x = C.elements (A.get (C.choose x))
>                                        ^^^^^^^^^^^^^^^^^^^^
> This expression has type ASet.t but is here used with type
>  C.t = Set.Make(A).t

You are suffering from the "double vision" problem. This arises when you 
have a recursive module with an abstract type and attempt to cross the 
abstraction boundary recursively. The type system does not make the abstract 
type recursively transparent. Here is a simpler example:

# module rec A : sig type t val f : t -> t end =
  struct type t = int let f (x : t) = A.f x end;;
This expression has type t = int but is here used with type A.t

You cannot do that in current Ocaml. The only way to avoid this problem is 
by making the type t transparent in the ascribed signature.

This problem actually is not straightforward to address on the 
type-theoretic level, and one of the reasons why recursive modules are 
pretty much an open research topic.

Hope this helps,
- Andreas


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-05-15 17:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-15 15:40 type aliases and recursive modules Josh Berdine
2007-05-15 16:29 ` [Caml-list] " Philippe Wang
2007-05-15 16:56   ` Josh Berdine
2007-05-15 17:11     ` Philippe Wang
2007-05-15 17:40     ` Andreas Rossberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).