[Alice-users] Re: CTM Chapter 6
Andreas Rossberg
rossberg at ps.uni-sb.de
Thu Jul 14 11:37:23 CEST 2005
Chris Rathman wrote:
>
> I had looked at Map at one time, thinking it might be what I was looking
> for, but I guess I wasn't persistent enough in my investigation. Is
> there sample code available so that I could have a go-by?
No, but it is really simple. For example, to have an (imperative)
dictionary over strings just define
structure Dict = MkRedBlackImpMap String
or, if you want it based on hashing,
structure Dict = MkHashImpMap String
Both produce a structure with the same signature, namely IMP_MAP
(http://www.ps.uni-sb.de/alice/manual/library/imp-map.html), with
String.t=string as their key type. I hope the documentation of the
signature is sufficient to make use of such maps - if not, please let us
know.
Usually a functional map type is preferable, in which case you do
structure Dict = MkRedBlackMap String
and you get a module of signature MAP
(http://www.ps.uni-sb.de/alice/manual/library/map.html).
Everything works analogous for sets.
> Also, while
> I'm on the subject, am I correct in assuming that the data structure
> libraries are written in Alice (i.e. not low-level)? If they are in
> Alice ML, where are they located? Been wanting to see if they can teach
> me a bit more about modules.
Well, they are in the Alice CVS, under lib/data. In the distribution
they are only contained in compiled form. But I'd say that their use of
modules isn't any more advanced than your examples are already - they
just define simple functors of the form
functor F (Key : ORDERED) ...
functor F (Key : HASHABLE) ...
where ORDERED and HASHABLE are straightforward signatures containing a
type, plus a respective ordering or hashing function (see
http://www.ps.uni-sb.de/alice/manual/library/ordered.html and
http://www.ps.uni-sb.de/alice/manual/library/hashable.html).
> Was kind of
> wondering though why the same sort of record accessor wouldn't work in
> the presence of the constructor. Something like:
>
> val x = Person{ name="George", age=25 }
> #age x
Well, this doesn't work for the same reason that, say,
#age (13, {name="George", age=25})
doesn't: the argument to a selector function must be of record type, not
something arbitrary just containing a record type. That is,
#age : {age:'a, ...} -> 'a
How could one specify a more general type for it? And in any case, what
should #age x possibly mean if I defined
datatype person = Person of {name:string, age:int} | ImmortalAlmighty
?
This is different from Oz, where the moral equivalents of datatypes and
records are mingled into one feature, and more importantly, where the
issue of static type safety is simply ignored (i.e. if you do x.age in
Oz you have no guarantee that it will succeed, you might encounter the
"wrong case").
> Strictly concerned with encapsulation in chapter 6. Inheritance and
> subtyping are covered in the next chapter, but unless I get comfortable
> with the encapsulation techniques, those aren't going to be within
> reach.
Subtyping simply won't work - you have to use explicit coercions.
Inheritance can be simulated to a certain extend, but will be ugly and
requires some repetition:
structure Point1D =
struct
type point = {getX : unit -> int, move : int -> unit}
fun new x' =
let
val x = ref x'
in
{getX = fn () => !x, move = fn x' => x:=x'}
end
end
structure ColoredPoint1D =
struct
type colored_point =
{super : Point1D.point,
getX : unit -> int,
move : int -> unit,
getColor : unit -> string,
dye : string -> unit}
fun new (x', c') =
let
val super = Point1D.new x'
val c = ref c'
in
{super, getX = #getX super, move = #move super,
getColor = fn () => !c, dye = fn c' => c:=c'}
end
end
val p = Point1D.new 5
val cp = ColoredPoint1D.new (7, "red")
val x1 = #getX p ()
val x2 = #getX cp ()
val xs = List.map (fn p => #getX p ()) [p, #super cp]
Some form of record extension syntax would make this nicer. You can
avoid the repetition in the type and record definitions at the price of
having to write something like
val x2 = #getX (#super cp) ()
every time you need to access an inherited message (which is terrible
with deeper inheritance).
Obviously, you won't have downcasts in either case...
> (And I'm assuming that
> the habit of making them truly abstract is the habit you are goading me
> to get into?)
Yes, absolutely :-)
Cheers,
- Andreas
--
Andreas Rossberg, rossberg at ps.uni-sb.de
Let's get rid of those possible thingies! -- TB
More information about the alice-users
mailing list