@@ -43,27 +43,65 @@ New algebraic data types can be added to the database context at any time via Tu
4343
4444### Implementation for Haskell Types
4545
46−Given a ```ProjectM36.Client``` ```Connection```, create an ```AddTypeConstructor``` with arguments a) type constructor name and b) data constructors.
46+Any Haskell ADT which implements the ```Atomable``` typeclass can be used directly as a database value or "atom" in Project:M36 parlance. The ```Atomable``` typeclass requires a set of prerequisite typeclasses be included, but, luckily, all of these typeclasses can be derived.
47+
48+Let's implement the ```Hair``` algebraic data type from the TutorialD example, but in Haskell. The full source code is available under the [examples directory](/examples/hair.hs).
49+
50+First, we define our data type and derive all the required typeclasses:
51+
52+```haskell
53+data Hair = Bald | Brown | Blond | OtherColor Text
54+ deriving (Generic, Show, Eq, Binary, NFData, Atomable)
55+```
56+
57+Note that the ```Atomable``` instance can also be derived.
58+
59+After setting up the connection (which we elide here), the database context is loaded with the expression to define the data type.
4760
48−Example:
4961```haskell
50−AddTypeConstructor (ADTypeConstructorDef "Hair" []) [DataConstructorDef "Brown" [], DataConstructorDef "Blond" [], DataConstructorDef "Bald" [],...]
62+executeDatabaseContextExpr sessionId conn (toDatabaseContextExpr (undefined :: Hair))
5163```
5264
53−Pass the ```AddTypeConstructor``` value to ```executeDatabaseContextExpr``` to add it to the database.
65+Using a ```Proxy``` would also be acceptable, but the result would be the same.
5466
55−To create a value for the new algebraic data type, create the type:
67+Next, we can create a relation variable named "people" containing our new data type alongside a person's name.
5668
5769```haskell
58−let hairType = ConstructedAtomType "Hair" M.empty
70+ let blond = NakedAtomExpr (toAtom Blond)
71+ executeDatabaseContextExpr sessionId conn (Assign "people" (MakeRelationFromExprs Nothing [
72+ TupleExpr (M.fromList [("hair", blond), ("name", NakedAtomExpr (TextAtom "Colin"))])]))
5973```
6074
61−then create the value:
75+To demonstrate that the new value is fully integrated with the database, we can create a restriction which matches against the value in the database.
6276
6377```haskell
64−let blondAtom = ConstructedAtom "Blond" hairType []
78+let restrictionPredicate = AttributeEqualityPredicate "hair" blond
79+peopleRelOrErr <- executeRelationalExpr sessionId conn (Restrict restrictionPredicate (RelationVariable "people" ()))
80+```
81+
82+Finally, we can print the resultant relation to show that it can be properly displayed (via the type's ```Show``` instance).
83+
84+```
85+TIO.putStrLn (showRelation peopleRel)
86+```
87+
88+```
89+┌──────────┬──────────┐
90+│hair::Hair│name::Text│
91+├──────────┼──────────┤
92+│Blond │"Colin" │
93+└──────────┴──────────┘
6594```
6695
67−The ```blondAtom``` can now be used in any place where an Atom is otherwise used such as in ```AtomExpr``` checking for equality in restriction or as an argument to ```AtomFunction```s or simply in building a new relation.
96+The essential ```Atomable``` typeclass functions are:
97+
98+| Function | Purpose |
99+| -------- | ------- |
100+| toAtom :: a -> Atom | convert a Haskell data type to a database atom |
101+| fromAtom :: Atom -> a | convert a database atom to a Haskell data type |
102+| toAtomType :: a -> AtomType | generate a database AtomType for a Haskell datatype |
103+| toDatabaseContextExpr :: a -> DatabaseContextExpr | generate a ```DatabaseContextExpr``` which can be executed against a database context in order to add the new type |
104+
105+In addition, basic Haskell data types like ```Int```, ```Text```, ```Bool```, ```UTCTime```, and more already have Atomable instances ready-to-go.
68106
69−In the previous example, the additional empty arguments are for polymorphic variables and arguments. In this simple ADT, there is no polymorphism necessary, so the arguments are empty.
107+To be clear, these data types are not black boxes once stored in the database. These new types can be scanned and manipulated by Haskell scripts which can be created at runtime. For more information, read about [```AtomFunction```s](/docs/atomfunctions.markdown).