# Fantas, Eel, and Specification 1: Daggy

Hello again, the Internet! As a functional programming zealot* and JavaScript developer, I spend a lot of my time raving about their crossover. In this series, we’ll look at the Fantasy Land spec in its entirety, and go through examples of how we can use the typeclasses within it. However, before we go any further, we need to talk about `daggy`.

Daggy is a tiny library for creating sum types for functional programs. Don’t worry about what that means too much for now, and focus on the two functions that the library exports: `tagged` and `taggedSum`.

## `daggy.tagged(typeName, fields)`

This is a very simple method for creating types with one constructor. In other words, think of it as a way to store your very rigid (probably model) data:

``````//- A coordinate in 3D space.
//+ Coord :: (Int, Int, Int) -> Coord
const Coord = daggy.tagged('Coord', ['x', 'y', 'z'])

//- A line between two coordinates.
//+ Line :: (Coord, Coord) -> Line
const Line = daggy.tagged('Line', ['from', 'to'])
``````

The resulting structures are pretty intuitive:

``````// We can add methods...
Coord.prototype.translate =
function (x, y, z) {
// Named properties!
return Coord(
this.x + x,
this.y + y,
this.z + z
)
}

// Auto-fills the named properties
const origin = Coord(0, 0, 0)

const myLine = Line(
origin,
origin.translate(2, 4, 6)
)
``````

This is nothing scary if you’ve used the JavaScript object system before: all the `tagged` function really does is give us a function to fill the given named properties on an object. That’s it. A tiny little utility for creating constructors with named properties.

## `daggy.taggedSum(typeName, constructors)`

Now for the interesting one. Think about the boolean type: it has two values, `True` and `False`. In order to represent a structure like `Bool`, we need to make a type with multiple constructors (what we call a sum type):

``````const Bool = daggy.taggedSum('Bool', {
True: [], False: []
})
``````

We call the different forms of our type its type constructors: in this case, they’re `True` and `False`, and neither has any arguments. How about we take our code from the `tagged` example and build up a more complicated type?

``````const Shape = daggy.taggedSum('Shape', {
// Square :: (Coord, Coord) -> Shape
Square: ['topleft', 'bottomright'],

// Circle :: (Coord, Number) -> Shape
})
``````

Unlike the boolean values, our constructors here have values. They take different values depending on which constructor we use, but we know that `Square` and `Circle` are definitely both constructors of the `Shape` type. How does this help us?

``````Shape.prototype.translate =
function (x, y, z) {
return this.cata({
Square: (topleft, bottomright) =>
Shape.Square(
topleft.translate(x, y, z),
bottomright.translate(x, y, z)
),

Shape.Circle(
centre.translate(x, y, z),
)
})
}

Shape.Square(Coord(2, 2, 0), Coord(3, 3, 0))
.translate(3, 3, 3)
// Square(Coord(5, 5, 3), Coord(6, 6, 3))

Shape.Circle(Coord(1, 2, 3), 8)
.translate(6, 5, 4)
// Circle(Coord(7, 7, 7), 8)
``````

Just as before, we are attaching methods to the `Shape` prototype. However, `Shape` isn’t a constructor, it’s a type: `Shape.Square` and `Shape.Circle` are the constructors.

This means that, when we write a method, we have to write something that will work for all forms of the `Shape` type, and `this.cata` is Daggy’s killer feature. By the way, `cata` is short for catamorphism!

All we do is pass a `{ constructor: handler }` object to the `cata` function, and the appropriate one will be called when the method is invoked. As we can see above, we now have a `translate` method that will work for both types of `Shape`!

We could even attach methods to our `Bool` type:

``````const { True, False } = Bool

// Flip the value of the Boolean.
Bool.prototype.invert = function () {
return this.cata({
False: () => True,
True: () => False
})
}

// Shorthand for Bool.prototype.cata?
Bool.prototype.thenElse =
function (then, or) {
return this.cata({
True: then,
False: or
})
}
``````

As you can see, for constructors with no arguments, we use handlers with no arguments. Note, too, that different constructors of the same sum type can have completely different numbers and types of arguments. This will be really important when we come to examples of the Fantasy Land structures.

This is all there is to `taggedSum`: it lets us build types with multiple constructors, and conveniently write methods for them.

## `List` but not least…

As a final example of `taggedSum` (because I hope `tagged` is nice and straightforward), here’s a linked list and a couple of useful functions:

``````const List = daggy.taggedSum('List', {
})

List.prototype.map = function (f) {
return this.cata({
),

Nil: () => List.Nil
})
}

// A "static" method for convenience.
List.from = function (xs) {
return xs.reduceRight(
(acc, x) => List.Cons(x, acc),
List.Nil
)
}

// And a conversion back for convenience!
List.prototype.toArray = function () {
return this.cata({
Cons: (x, acc) => [
x, ... acc.toArray()
],

Nil: () => []
})
}

// [3, 4, 5]
console.log(
List.from([1, 2, 3])
.map(x => x + 2)
.toArray())
``````

Sure enough, we can build a list with two constructors, `Cons` and `Nil` (as we did with `[x, ... xs]` and `[]` in my last post), and every list object will have a corresponding array object. For example, `[1, 2, 3]` becomes `Cons(1, Cons(2, Cons(3, Nil)))`, so it’s pretty obvious to see how any list can be translated!

That’s everything you need to know about `daggy` to understand Fantasy Land! If you want to cement your understanding, why not try to add a couple more array functions to the `List` type like `filter` or `reduce`?

Otherwise, we have one more thing to talk about before we get involved in the structures: type signatures!

Until then, take care! ♥

* My (verbatim) introduction by Dan to members of the PHP core team.

Even if only by a technicality.

We call this an isomorphism!