Skip to content

Instantly share code, notes, and snippets.

@eduardoleon
Last active November 9, 2015 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eduardoleon/1e8ad9174ec5ae0386dd to your computer and use it in GitHub Desktop.
Save eduardoleon/1e8ad9174ec5ae0386dd to your computer and use it in GitHub Desktop.
create table male
( male_id int not null
, name varchar(100) not null
, primary key (male_id) );
create table female
( female_id int not null
, name varchar(100) not null
, primary key (female_id) );
create view person as
select 'm' as gender, male_id as person_id, name from male
union
select 'f' as gender, female_id as person_id, name from female;
-- let's say we're given (@gender, @person_id, @new_name),
-- and we want to update the corresponding person's name
if @gender = 'm'
update male set name = @new_name where male_id = @person_id
else if @gender = 'f'
update female set name = @new_name where female_id = @person_id
else
-- what do?? we've been given crap data, this should be impossible
-- types are supposed to prevent this kind of error!
-- every table has an autogenerated id field
-- for primitive tables, it's an abstract type (internally an autoincremental int)
-- for derived tables, it's an ML-like sum (variant) or product (tuple)
-- in my system, there are no null fields whatsoever,
-- so `not null` annotations are unnecessary
create table male
primitive
fields ( minus_factor numeric )
create table female
primitive
fields ( plus_factor numeric )
create table person
derived = Male of male
| Female of female
fields ( name varchar(100)
, health numeric )
-- let's say we are given (@person, @new_name),
-- and we want to update the corresponding person's name
set @person.name := @new_name
-- let's say we are given (@person)
-- if it's a male, we want to decrease their health by 20%
-- if it's a female, we want to decrease their health by 10%
set @person.health := @person.health *
(case @person of
Male _ => 0.8
| Female _ => 0.9)
-- let's say we want to decrease the health of all males by their minus_factor
-- and increase the health of all females by their plus_factor
forall [@person : person]
set @person.health := @person.health *
(case @person of
Male @male => (1 - @male.minus_factor)
| Female @female => (1 + @female.plus_factor))
-- alternatively we could do this:
forall [@male : male]
let @person = Male @male in
set @person.health := @person.health * (1 - @male.minus_factor)
forall [@female : female]
let @person = Female @female in
set @person.health := @person.health * (1 + @female.plus_factor)
@spion
Copy link

spion commented Nov 9, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment