Algebraic Types
A language to share data representation
Modeling a shape
Point Circle Radius Rectangle Width Height
OOP Solution
Shape
Abstract class
drawAt(x,y)
OOP Solution
Point
drawAt(x,y) { ...}
Shape
Abstract class
drawAt(x,y)
Circle
Attribute: radius
drawAt(x,y) { ...}
Rectangle
Attributes:
width, height
drawAt(x,y) { ...}
OOP Solution
- Classes
- Abstract classes
- Inheritance
- Method
- (this/self)
Modeling a shape
Point Circle Radius Rectangle Width Height
Modeling a shape
Point Circle Radius Rectangle Width Height
Modeling a shape
type Shape =
Point | Circle Radius | Rectangle Width Height
Modeling a shape
type Shape =
Point | Circle Radius | Rectangle Width Height
type alias Radius = Float
type alias Width = Float
type alias Height = Float
Modeling a shape
type Shape =
Point | Circle Radius | Rectangle Width Height
type alias Radius = Float
type alias Width = Float
type alias Height = Float
Equivalent:
type Shape =
Point | Circle Float | Rectangle Float Float
Modeling a shape
type Shape =
Point | Circle Radius | Rectangle Width Height
type alias Radius = Float
type alias Width = Float
type alias Height = Float
Equivalent:
type Shape =
Point | Circle Float | Rectangle Float Float
Algebraic Data Type !
Use an ADT
myRect = Rectangle 10 20
bigCircle = Circle 420000
drawAt (x, y) shape =
case shape of
Point ->
...
Circle radius ->
...
Rectangle width height ->
...
myDrawing1 = drawAt (5, 7) (Circle 10)
myDrawing2 = drawAt (10, 5) myRect
Advanced shape
R. I. P.
Bob
Advanced shape
tombstone =
(Rectangle 50 50)
Advanced shape
tombstone =
Union
(Rectangle 50 50)
(Circle 25)
Advanced shape
shift
tombstone =
Union
(Rectangle 50 50)
(Circle 25)
(0, 25)
-- the circle is
-- shifted by 25
-- vertically
Advanced shape
shift
type Shape
= Point
| Circle Radius
| Rectangle Width Height
| Union Shape Shape Shift
type alias Shift =
(Float, Float)
Advanced shape
And more:
- intersection
- symmetric difference
- rotation
- ...
Translation
Todo list
Appeler Bob
Lire H2G2
Tester Elm
New
3 elements
Translation
Todo list
3 elements
New
Title
Appeler Bob
Lire H2G2
Tester Elm
Translation
Todo list
3 elements
New
NumberOfElements 3
Title
Appeler Bob
Lire H2G2
Tester Elm
Translation
Todo list
3 elements
New
New
Title
Appeler Bob
Lire H2G2
Tester Elm
NumberOfElements 3
Translation
Todo list
3 elements
New
Title
New
type StaticText
= Title
| NumberOfElements Int
| New
Appeler Bob
Lire H2G2
Tester Elm
NumberOfElements 3
renderEnglish text =
case text of
Title ->
"Todo list"
NumberOfElements n ->
toString n ++ " elements"
New ->
"New"
renderEnglish text =
case text of
Title ->
"Todo list"
NumberOfElements n ->
case n of
0 ->
"You have nothing to do!"
1 ->
"One more thing to do!"
_ -> --default case
toString n ++ " elements"
New ->
"New"
renderFrench text =
case text of
Title ->
"À faire !"
NumberOfElements n ->
case n of
0 ->
"Tu n'as rien à faire !"
1 ->
"Une seule chose à faire !"
_ -> --default case
toString n ++ " élements"
New ->
"Nouveau"
Translation
À faire !
Nouveau
3 élements
Appeler Bob
Lire H2G2
Tester Elm
Can I use?
(non-exhaustive)
FULL SUPPORT
ML-family
Haskell, Elm, PureScript, ReasonML, OCaml, ...
Rust
Scala
PARTIAL SUPPORT
TypeScript
Define ADTs: Ok Pattern matching:
... hack it yourself!
EMULATION
All languages!
(not recommended)
DEMAND EXPRESSIVENESS FROM YOUR LANGUAGE!
Pratical introduction to algebraic data types
By sebbes
Pratical introduction to algebraic data types
- 230