As seen below, it's pretty easy.
this can be
general rules:
animals' accepted food:
when slaughtered:
| Python | 0/11 should_fails detected at compile-time |
| Ruby | 0/11 should_fails detected at compile-time |
| Scheme | 0/11 should_fails detected at compile-time |
| C++ | 5/11 should_fails detected at compile-time |
| C++ with parametric class | 7/11 should_fails detected at compile-time |
| C++ with parametric class and diamond multiple-inheritance | 8/11 should_fails detected at compile-time |
| C++ with parametric class and eaters tied to the food | 8/11 should_fails detected at compile-time |
| OCaml | 5/11 should_fails detected at compile-time |
| OCaml with parametric class tentative | 1/11 should_fails succeeds :-(, 7/11 should_fails detected at compile-time |
| OCaml with parametric class and variants | 8/11 should_fails detected at compile-time |
| Prolog tentative | 3/11 should_fails succeeds :-( and 0/11 detected at compile-time |
| Haskell faking OO, no monad | 5/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used |
| Haskell with phantom types (simple) | 8/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used |
| Haskell with phantom types (with type hierarchy) | 8/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used |
| Haskell with monads and phantom types | 8/11 should_fails detected at compile-time |
| Scala | 11/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used |
| ATS (test code) | 11/11 should_fails detected at compile-time |
| Typescript | 8/11 should_fails detected at compile-time |
| Java | 5/11 should_fails detected at compile-time |
| Java with generics | 8/11 should_fails detected at compile-time |
grass = new_grass(5)
carrot = new_carrot(10)
a_rabbit = new_rabbit(100)
a_cow = new_cow(1000)
a_human = new_human(300)
another_human = new_human(350)
for o in [ a_rabbit, a_cow, a_human ]:
print "%s -> %d" % (o.name, o.energy)
a_rabbit.eat(carrot)
a_cow.eat(grass)
a_dead_rabbit = a_rabbit.slaughter()
a_beef = a_cow.slaughter()
a_human.eat(carrot)
a_human.eat(carrot)
a_human.eat(a_beef)
a_human.eat(a_dead_rabbit)
a_human.eat(another_human.slaughter())
if a_human.energy != 1785: raise "failed"
and here are some examples that should fail
new_cow(10).slaughter().eat(grass) # meat (food) can't eat new_cow(10).slaughter().slaughter() # meat (food) can't be slaughtered carrot.eat(grass) # vegetable (food) can't eat carrot.slaughter() # vegetable (food) can't be slaughtered new_cow(10).eat(carrot) # cow do not eat carrot new_cow(10).eat(new_cow(10).slaughter()) # cow do not eat beef a_human.eat(new_cow(10)) # can't eat live animals a_human.eat(grass) # human do not eat grass a_human.eat(a_beef) # a_beef is already eaten a_cow.eat(grass) # a_cow is dead, it can't eat a_cow.slaughter() # a_cow is dead, it can't be slaughtered again
Release: $Id$