Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Is a Cow an Animal?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: james woodyatt <jhw@w...>
Subject: Re: [Caml-list] Is a Cow an Animal?
On Wednesday, April 17, 2002, at 04:40 PM, Pixel wrote:

> Based on
>   http://www.visviva.com/transframe/papers/covar.htm
>   http://pauillac.inria.fr/~remy/work/virtual/virtual005.html
>
> I made
>   http://merd.net/pixel/language-study/various/is-a-cow-an-animal/
> and especially
>   http://merd.net/pixel/language-study/various/is-a-cow-an-
> animal/ocaml2.listing
>
> Please help with some pbs!

Your problem is an extension of the one documented by Didier Remy, and 
it's very similar to one I faced with the Iox library I posted 
recently.  I suspect it's a really, really common problem.

I read the statement on your page, and took a swing at it.  Wasn't too 
difficult.

I borrowed a technique I learned here from Brian Rogoff that uses an 
abstract type with a contravariant type parameter for passing the type 
of energy a food object contains to an animal object that can eat it.  
(I wish I were smart enough to know the name for this technique.)

I also used the functional style because the problem statement had some 
language about ensuring that animals are never slaughtered twice.  You 
really can't do that at compile time in Caml, but you could pretty 
easily modify the code I present below so that it raises Failure if the 
'consume' method is called on the same meat object more than once, or if 
an energy value is fed to more than one animal.

I think the code demonstrates more flexibility as I show it here.

(*======================= pixelworld.mli ======================*)
type -'diet energy

class ['diet] thing:
     int ->
     object
         val energy: 'a energy
         method energy: int
     end

class type ['diet] food =
     object('a)
         inherit ['diet] thing
         method consume: 'diet energy * 'a option
     end

class type ['diet] vegetable = ['diet] food
class type ['diet] meat = ['diet] food

class grass: int -> [[ `E_cow ]] vegetable
class carrot: int -> [[ `E_rabbit | `E_human ]] vegetable
class type beef = [[ `E_human ]] meat
class type coney = [[ `E_human ]] meat
class type longpig = [[ `E_human ]] meat

class ['diet, 'eater] animal:
     int ->
     object('a)
         inherit ['diet] thing

         method feed: 'diet energy -> 'a
         method slaughter: 'eater meat
     end

class cow: int -> [[ `E_cow ], [ `E_human ]] animal
class rabbit: int -> [[ `E_rabbit ], [ `E_human ]] animal
class human: int -> [[ `E_human ], [ `E_human ]] animal

(* end of signature *)

(*======================= pixelworld.ml ======================*)
type 'diet energy = int

class ['diet] thing (e : int) =
     object
         val energy: 'diet energy = e
         method energy: int = energy
     end

class type ['diet] food =
     object('a)
         inherit ['diet] thing
         method consume: 'diet energy * 'a option
     end

class ['diet] vegetable e : ['diet] food =
     object
         inherit ['diet] thing e
         method consume = energy, Some {< >}
     end

class ['diet] meat e : ['diet] food =
     object(_:'a)
         inherit ['diet] thing e
         method consume = energy, (None : 'a option)
     end

class grass = [[ `E_cow ]] vegetable
class carrot = [[ `E_rabbit | `E_human ]] vegetable
class beef = [[ `E_human ]] meat
class coney = [[ `E_human ]] meat
class longpig = [[ `E_human ]] meat

class ['diet, 'eater] animal e =
     object
         inherit ['diet] thing e

         method slaughter = ((new meat energy) : 'eater meat)
         method feed (x : 'diet energy) = {< energy = energy + x >}
     end

class cow = [[ `E_cow ], [ `E_human ]] animal
class rabbit = [[ `E_rabbit ], [ `E_human ]] animal
class human = [[ `E_human ], [ `E_human ]] animal

(* end of module *)

--
j h woodyatt <jhw@wetware.com>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners