This is example code as suggested on FunctionalModeling. Code collected by ShaeErisson
module Truck where -- http://c2.com/cgi-bin/wiki?FunctionalModeling -- 1. truck and tire as types -- we alias Pressure to Integer here, following the OnceAndOnlyOnce principle type Pressure = Integer -- tire as unification type data Tires = Michelin Pressure | Pirelli Pressure checkPressure :: Tires -> Pressure checkPressure (Michelin pressure) = pressure checkPressure (Pirelli pressure) = pressure {- interactively: *Truck> let x = Pirelli 5 *Truck> checkPressure x 5 -} -- 2. tire as typeclass -- a typeclass describes an operation -- any type can provide an implementation of this operation class Tire a where getPressure :: a -> Pressure -- some random type data MyFoo? = Foo Pressure deriving (Show, Eq) instance Tire MyFoo? where getPressure (Foo a) = a {- interactively: *Truck> let y = Foo 5 *Truck> getPressure y 5 -} -- 3. unified type with records -- from HalDaume? III -- a record is ... well.. like a database record sort of... data Tires' = Michelin' { checkPressure' :: Pressure } | Pirelli' { checkPressure' :: Pressure } -- 4. alternate tire typeclasses -- from EsaPulkkinen class Tire' a where createTire' :: Pressure -> a getPressure' :: a -> Pressure -- Esa: This will cause some problems for the user -- Esa: he has to choose a representation -- Esa: that is, getPressure (createTire x) does not work. -- another idea is to use a factory to build tires class Tire'' a where getPressure'' :: a -> Pressure class TireFactory?'' f where createTire :: Tire'' a => f a -> Pressure -> a data MyTireFactory a = MyTireFactory { myTireFromPressure :: Pressure -> a } data MyTire = MyTire { myTirePressure :: Pressure } myTireFactory :: MyTireFactory MyTire myTireFactory = MyTireFactory (\p -> MyTire p) instance TireFactory'' MyTireFactory where createTire (MyTireFactory f) p = f p instance Tire'' MyTire where getPressure = myTirePressure -- Esa: you could embed Pressure in the factory as well -- Esa: so that constructing factory will be the place where the pressure is required. -- Esa: you could have a design where a car encloses all tire and pressure handling class Car c t where getTires :: c -> [t] getPressure :: c -> t -> Pressure class Car' c where getTires :: c t -> [t] getPressure :: c t -> t -> Pressure -- Esa: but that has a problem that it does not properly describe -- Esa: the connection between a tire and a car -- Esa: [or you have to handle error cases -- Esa: where you ask a pressure from a tire -- Esa: that is not in the same car that you specified] -- Esa: Another alternative is to represent this using a mapping from cars to tires: class CarTireMapping? m where getTires :: m c t -> c -> [t] getPressure :: m c t -> t -> Pressure -- Truck class using functional dependencies -- from AndrewBromage (under construction) -- class Truck truck tyre | truck -> tyre where { ... }