caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: james woodyatt <jhw@wetware.com>
To: Pixel <pixel@mandrakesoft.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Is a Cow an Animal?
Date: Thu, 18 Apr 2002 11:58:53 -0700	[thread overview]
Message-ID: <538FE5B6-52FE-11D6-9686-000502DB38F5@wetware.com> (raw)
In-Reply-To: <lyzo01q4gq.fsf@leia.mandrakesoft.com>

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


  parent reply	other threads:[~2002-04-18 18:58 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-04-17 23:40 Pixel
2002-04-18  2:17 ` John Max Skaller
2002-04-18 10:19   ` Pixel
2002-04-18 12:09     ` Pixel
2002-04-18 12:52       ` Jacques Garrigue
2002-04-18 13:03         ` Pixel
2002-04-18 18:58 ` james woodyatt [this message]
2002-04-18 22:44   ` Pixel
2002-04-18 22:57     ` james woodyatt
2002-04-18 23:31       ` Pixel
2002-04-19  0:21   ` Remi VANICAT
2002-04-19  0:51     ` james woodyatt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=538FE5B6-52FE-11D6-9686-000502DB38F5@wetware.com \
    --to=jhw@wetware.com \
    --cc=caml-list@inria.fr \
    --cc=pixel@mandrakesoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).