# PureScript: RowToList

I recently added the `RowToList`

and `ListToRow`

type classes to the 2.3.0
release of the typelevel-prelude under the `Type.Row`

module. The idea with these two type classes is to be able to compute at the
type-level with rows of types. This is achieved by converting to/from a
type-level cons-list:

This describes that entries in a `RowList`

are pairs of symbols and types.

The `RowToList`

type class converts from a row of types to a `RowList`

. It is
solved by the compiler (as of version 0.11.6) and is defined as:

It extracts the collection of entries in a closed row of types. The list of entries is sorted by label but preserves order of duplicates.

Here are a few examples with a given input row and the computed `RowList`

:

The (almost) inverse of this operation is `ListToRow`

- which takes a `RowList`

and computes a row of types from it. This type class is straight-forwardly
defined by recursively applying a `RowCons`

:

Note that a `RowList`

need not have sorted keys for `ListToRow`

to produce a
row. The list produced by `RowToList row list`

should produce the same `row`

when passed to `ListToRow list row`

, but not necessarily the other way around.

## Example

A good demonstration of the kinds of things we can do with these type classes
is an `applyRecord`

function. This will accept a record of functions and a
record of inputs, producing a record of outputs. Such that each key in the
input and the output may have distinct types.

First we’ll write out the type of `applyRecord`

:

Here I’m using `i`

, `o`

, and `io`

to indicate input, output, and functions from
input to output; respectively.

Now for the type class:

Notice all those functional dependencies. To be able to compute the any of these types we need to know the other two.

There’s only one instance of the above type class, and it’s a fairly
straight-forward conversion of each of the rows to `RowList`

, then delegate to
an `ApplyRowList`

type class, and finally convert back to row. The conversions
are constrained to be inverses of each other.

The `ApplyRowList`

is (as you might expect) a version of `ApplyRecord`

, except
instead of working with rows of types, it works with `RowList`

.

Almost exactly the same as the previous type class, just working at a different kind.

Now that we have list representations of the rows, we can recursively process
them! The first case to deal with is `Nil`

. Remember that all the records
must have the same keys. So when we hit `Nil`

, they must all be `Nil`

:

Very easy.

Next up is the `Cons`

case. Again all three lists must be `Cons`

at the same
time. Not only that, but they must have the same keys in the same order.

Notice the relationship between the entries here: `i -> o`

, `i`

, and `o`

.

As an instance constraint, we recursively compute on the tails of each `Cons`

.

…and we’re done! At least the type computation part. We could write
`applyRecord`

with the FFI - which I’ll leave out as an implementation detail.

To demonstrate that this works, here are a few examples:

## Conclusion

Hopefully this has given you some insight into how the `RowToList`

and
`ListToRow`

type classes have given us super powers in dealing with rows. For
example, we can now define `Show`

and `Eq`

instances for records!

I look forward to seeing all the fun things people do with this :)

## Update 2017-09-24

In the previous version of this post I had the fundeps as:

This was incorrect, for example knowing just the input can’t tell you the output.