# Langton's Ant Redux, and Unrestricted Types

Fri Sep 26, 2014So this past Wednesday was the monthly Toronto Haskell User Group meeting, and I used the opportunity to A) show off my Langton's Ant implementation to people that might be able to offer pointers and B) ask a question about types that I'd been thinking about. We'll handle those in reverse order, with a bit of exposition on the question.

### Splay Trees

Here's a Haskell implementation of a Splay Tree not interesting enough to dwell on:

```
module SplayTree (Tree(..), fromList, SplayTree.elem, insert, remove) where
data Tree a = Node { value :: a
, left :: Tree a
, right :: Tree a }
| Empty deriving (Eq, Ord, Show, Read)
rotateR Empty = Empty
rotateR tree@(Node _ Empty _) = tree
rotateR (Node val (Node child ll lr) right) = Node child ll (Node val lr right)
rotateL Empty = Empty
rotateL tree@(Node _ _ Empty) = tree
rotateL (Node val left (Node child rl rr)) = Node child (Node val left rl) rr
insertRaw :: Ord a => Tree a -> a -> Tree a
insertRaw Empty a = Node a Empty Empty
insertRaw tree@(Node val left right) a
| a == val = tree
| a > val = Node val left $ insertRaw right a
| otherwise = Node val (insertRaw left a) right
fromList :: Ord a => [a] -> Tree a
fromList lst = foldl (\memo a -> splayTo (insertRaw memo a) a) Empty lst
splayTo :: Ord a => Tree a -> a -> Tree a
splayTo Empty _ = Empty
splayTo tree@(Node val left right) a
| a == val = tree
| a > val = rotateL $ Node val left $ splayTo right a
| otherwise = rotateR $ Node val (splayTo left a) right
elem :: Ord a => Tree a -> a -> Maybe (a, Tree a)
elem tree a = case a == value splayed of
True -> Just (a, splayed)
_ -> Nothing
where splayed = splayTo tree a
insert :: Ord a => Tree a -> a -> Tree a
insert tree elem = splayTo (insertRaw tree elem) elem
remove :: Ord a => Tree a -> a -> Tree a
remove tree elem = if root == elem
then deleteRoot splayed
else tree
where splayed@(Node root _ _) = splayTo tree elem
deleteRoot :: Tree a -> Tree a
deleteRoot (Node val Empty Empty) = Empty
deleteRoot tree@(Node val left Empty) = Node (rightLeaf left) (trim left) Empty
where rightLeaf (Node val _ Empty) = val
rightLeaf (Node _ _ right) = rightLeaf right
trim (Node _ Empty Empty) = Empty
trim (Node _ left Empty) = left
trim (Node val left right) = Node val left $ trim right
deleteRoot tree@(Node val left right) = Node (leftLeaf right) left (trim right)
where leftLeaf (Node val Empty _) = val
leftLeaf (Node _ left _) = leftLeaf left
trim (Node _ Empty Empty) = Empty
trim (Node _ Empty right) = right
trim (Node val left right) = Node val (trim left) right
```

Notice in particular that the `Tree`

type has an unrestricted `a`

in it.

```
-- v
data Tree a = Nod...
-- ^
```

but most of the manipulation functions that act on a `Tree a`

*do* have a restriction

```
...
insertRaw :: Ord a => Tree a -> a -> Tree a
...
fromList :: Ord a => [a] -> Tree a
...
splayTo :: Ord a => Tree a -> a -> Tree a
...
elem :: Ord a => Tree a -> a -> Maybe (a, Tree a)
...
insert :: Ord a => Tree a -> a -> Tree a
...
remove :: Ord a => Tree a -> a -> Tree a
...
```

They all need an `a`

that's a member of the `Ord`

typeclass. That is, you need to be able to run `compare`

on the elements of a Splay Tree in order for it to do you any good.

So from my perspective, the unrestricted `a`

in my `data`

declaration feels like lying. I'm giving the impression that you can make a tree out of anything, when in fact you can only make a tree out of anything *you can sort*. My question was, "Is there a way to restrict this structure at the type level?". What I wanted to write was something like

```
data Ord a => Tree a = Nod...
```

To paraphrase Ben Darwin and Albert Lai,

### You Don't Want That

As it happens, they managed to convince me of this. Here's a paraphrase of the argument they used; maybe it'll work on you too.

There are only two ways you'll ever want to export your type. You either want to export it as a black box, or you want to export it in a non-opaque way so that your users can see some or all of its implementation details. If you're going the black box route

```haskell module Foo (YourTypeConstructor, apiFn, apiFn', apiFn''...) where ... ```

then your users are

onlygoing to be interacting with your type through your API functions, which are already suitably annotated, and restricted to valid inputs, so there's no need to redundantly restrict the type. If you're going the non-opaque route|1|,```haskell module Foo (YourTypeConstructor(..), apiFn, apiFn', apiFn''...) where ... ```

then your users might ignore some or all of your API, and just use your structure. In doing so, they may find a purpose for it that

doesn'trequire its elements to be members of`Ord`

. In this case, you would be doing them a disservice by restricting your type declaration.

And I'll buy that.

So I don't really want a restricted `Tree`

, I just want restricted manipulation functions, which I have. Case closed.

### Langton's Haskelly Ant Redux

I also ended up showing off my ants implementation. I'm near the bottom in terms of Haskell skill-level at the group, so the explanation went quite quickly. The only part there was any confusion about was the admittedly over-complicated `animate`

function. I mentioned that ideally, I'd want to write something like

```
iterateM_ (\w -> do { printWorld w ; wait 10 ; step w }) test
```

instead of the code I had actually written, but didn't have `iterateM_`

. The group considered that no excuse, and promptly found a definition from Control.Monad.Loop|2| via Hayoo. It turned out to be a bit more baroque than necessary.

```
iterateM_ :: Monad m => (a -> m a) -> a -> m b
iterateM_ f = g
where g x = f x >>= g
```

I was feeling a bit intimidated by that, but the group pushed me to write my own, starting with just the type signature. "It's extremely simple", they said, "and should really use `do`

-notation", unless I shared the Control.Monad.Loop writers' apparently bizarre taste for point-free style. They were right:

```
loop :: Monad m => (a -> m a) -> a -> m b
loop f a = do res <- f a
loop f res
```

Tadaah.

With that, we can basically write `animate`

out of existence entirely by re-defining `main`

as

```
main :: IO ()
main = concurrent $ loop nextFrame (test, 0)
where nextFrame (w, ct) = do liftIO $ setContent "world" $ showWorld w
liftIO $ setContent "generations" $ show ct
wait 50
return $ (step w, succ ct)
```

which is at once easier for me to read, and apparently more idiomatic than the `setTimeout`

recursion I had set up last time. The `concurrent`

call at the top, and the `liftIO`

s in `nextFrame`

are there because `wait`

|3| is a monadic function introduced in Haste, but it's in a monad called `CIO`

, whose goal is to be used for client-side concurrency, while `setContent`

, and more importantly `main`

, are both plain `IO ()`

functions.

The complete revised code, and recompiled `.js`

are both up at the same CodeRetreat github.

##### Footnotes

1 - |back| - Incidentally, the example below exports *all* internals of `YourTypeConstructor`

, but the argument works whenever you expose any internal implementation detail to your users, not just at the transparent extreme.

2 - |back| - This would be a hackage link, but it's down as I write this. It probably won't be by the time I get around to the next draft, but it happens with irritating regularity when I'm collecting links for these pieces.

3 - |back| - Scroll down to the bottom for the actual documentation of `wait`

; it doesn't have a direct link target.