- Hello, I'm trying to manage with constructed types in a particular way,

can anyone tell me if it is a "really bad" way?

I want to use 'a lists with an additionnal type information : 'b.

Here is the type declaration: (ocaml 3.04)

# type ('a,'b) t = 'a list;;

type ('a, 'b) t = 'a list

I have a cons:

# let f (x:'a) (y:('a,'b) t) = (x::y : ('a,'b) t);;

val f : 'a -> ('a, 'b) t -> ('a, 'b) t = <fun>

Then a value :

# let (v: (int,bool) t) = [1];;

val v : (int, bool) t = [1]

The problem is when I do a "cons" on it:

# f 1 v;;

- : (int, '_a) t = [1; 1]

the "bool" information has diseappeared !!

Any ideas?

Julien Cohen - Hi,

On Fri, Oct 18, 2002 at 01:49:30PM +0200, Julien Cohen wrote:

>

> # type ('a,'b) t = 'a list;;

> # let f (x:'a) (y:('a,'b) t) = (x::y : ('a,'b) t);;

> # let (v: (int,bool) t) = [1];;

> # f 1 v;;

> - : (int, '_a) t = [1; 1]

> the "bool" information has diseappeared !!

This is strange, indeed. It deserves a message in the Caml List or

at Caml bugs.

--

Daniel de RAUGLAUDRE

daniel.de_rauglaudre@...

http://cristal.inria.fr/~ddr/ - Julien Cohen <jcohen@...> writes:

> Hello, I'm trying to manage with constructed types in a particular way,

It look like you are trying to do something similar to phantom type,

> can anyone tell me if it is a "really bad" way?

so you may be very interested by the following :

http://caml.inria.fr/archives/200109/msg00097.html

well, this add something to what you are trying : opaque polymorphism.

>

the problem is that the compiler know that ('a,'b) t = 'a list and use

>

> I want to use 'a lists with an additionnal type information : 'b.

> Here is the type declaration: (ocaml 3.04)

>

> # type ('a,'b) t = 'a list;;

> type ('a, 'b) t = 'a list

>

> I have a cons:

>

> # let f (x:'a) (y:('a,'b) t) = (x::y : ('a,'b) t);;

> val f : 'a -> ('a, 'b) t -> ('a, 'b) t = <fun>

>

> Then a value :

>

> # let (v: (int,bool) t) = [1];;

> val v : (int, bool) t = [1]

>

>

> The problem is when I do a "cons" on it:

>

> # f 1 v;;

> - : (int, '_a) t = [1; 1]

>

> the "bool" information has diseappeared !!

>

this information to make your code more polymorphic. It's a clever

thing, but it not what you want.

There is two known solution :

# type ('a,'b) t =

| Cons of 'a * ('a,'b) t

| Nil;;

type ('a, 'b) t = Cons of 'a * ('a, 'b) t | Nil

# let v = (Cons (1, Nil) : (int,bool) t);;

val v : (int, bool) t = Cons (1, Nil)

# Cons (1, v);;

- : (int, bool) t = Cons (1, Cons (1, Nil))

Here I'm redefining a list type. The problem is that you wont be able

to use the stdlib List operation.

then there is the module solution, using abstraction to forget the

type information :

# module type TTYPE =

sig

type ('a,'b) t

val empty : ('a, 'b) t

val f : 'a -> ('a, 'b) t -> ('a, 'b) t

val to_list : ('a, 'b) t -> 'a list

end;;

module type TTYPE =

sig

type ('a, 'b) t

val empty : ('a, 'b) t

val f : 'a -> ('a, 'b) t -> ('a, 'b) t

val to_list : ('a, 'b) t -> 'a list

end

# module T : TTYPE =

struct

type ('a,'b) t = 'a list

let empty = []

let f x y = x :: y

let to_list x = x

end ;;

module T : TTYPE

then :

# let v = (T.f 1 T.empty : (_, bool) T.t);;

val v : (int, bool) T.t = <abstr>

# T.f 1 v;;

- : (int, bool) T.t = <abstr>

the problem here is that the type t become abstract : you can't use

stdlib function on it without using the to_list function.

You may want to define some other function on it to be able to use

your type information more easily.

--

RĂ©mi Vanicat

vanicat@labri.u-bordeaux.fr

http://dept-info.labri.u-bordeaux.fr/~vanicat