Functional Modeling Examples

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 { ... }


EditText of this page (last edited November 5, 2011) or FindPage with title or text search