To: caml-list@inria.fr
Subject: Repeat: Question about corecursive type and class types (w/ answer)
From: John Prevost <prevost@maya.com>
Date: 27 Jan 1999 21:37:22 -0500
I asked this a bit ago, but didn't receive any answer.
In order to do something like restricted downcasting, I'd like to say
something equivalent to the following:
type objsum =
| A of a
| B of b
and class type super =
object
method as_objsum : objsum
...
end
and class type a =
object
inherit super
...
end
and class type b =
object
inherit super
...
end
I was not able to do the above because you can't define a type and a
class type in the same set of and s. I was able to do the following:
type objsum' =
| A' of a'
| B' of b'
and super = < to_objsum' : objsum'; ... >
and a = < to_objsum' : objsum'; ... >
and b = < to_objsum' : objsum'; ... >
This second version is rather less acceptable, since if the class type
has a large number of methods (as can occur when you're doing a bit of
inheritance), there can be problems.
I've finally discovered a way to do what I want to do--although I
think it may be possible to make it easier to define. (I was looking
at the parser, and it didn't seem easy to make the change, though.)
Here's the workaround:
class type ['a] super =
object
method downcast : 'a
end
class type ['a] a =
object
inherit ['a] super
method do_a : int
end
class type ['a] b =
object
inherit ['a] super
method do_b : float
end
type objsum =
| A of objsum a
| B of objsum b
And to show that it works, the following (with the above assumed):
# class test_a =
object (s)
method downcast = A (s :> objsum a)
method do_a = 1
end
class test_b =
object (s)
method downcast = B (s :> objsum b)
method do_b = 1.0
end;;
class test_a : object method do_a : int method downcast : objsum end
class test_b : object method do_b : float method downcast : objsum end
# let ta = new test_a
let tb = new test_b;;
val ta : test_a = <obj>
val tb : test_b = <obj>
# let ta' = (ta :> objsum super)
let tb' = (tb :> objsum super);;
val ta' : objsum super = <obj>
val tb' : objsum super = <obj>
# ta'#do_a;;
Characters 0-3:
This expression has type objsum super
It has no method do_a
# let (A ta'3) = ta'#downcast
let (B tb'3) = tb'#downcast;;
Characters 5-11:
Warning: this pattern-matching is not exhaustive.
Characters 34-40:
Warning: this pattern-matching is not exhaustive.
val ta'3 : objsum a = <obj>
val tb'3 : objsum b = <obj>
# ta'3#do_a;;
- : int = 1
# tb'3#do_b;;
- : float = 1
This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:18 MET