Posted on December 27, 2014

In keeping with the rest of the “Examining Hackage” series I’d like to go through the source `folds`

package today. We’ll try to go through most of the code in an attempt to understand what exactly `folds`

does and how it does it. To be honest, I hadn’t actually heard of this one until someone mentioned it to me on /r/haskell but it looks pretty cool. It also has the word “comonadic” in the description, how can I resist?

It’s similar to Gabriel’s `foldl`

library, but it also seems to provide a wider suite of types folds. In retrospect, folds has a general framework for talking about types of folds and composing them where as `foldl`

defines only 2 types of folds, but defines a whole heap of prebuilt (left) folds.

## Poking Around

After grabbing the source and looking at the files we see that `folds`

is actually reasonable large

```
~$ cabal get folds && cd folds-0.6.2 && ag -g "hs$"
src/Data/Fold.hs
src/Data/Fold/L.hs
src/Data/Fold/L'.hs
src/Data/Fold/Class.hs
src/Data/Fold/M1.hs
src/Data/Fold/L1.hs
src/Data/Fold/R.hs
src/Data/Fold/Internal.hs
src/Data/Fold/L1'.hs
src/Data/Fold/R1.hs
src/Data/Fold/M.hs
Setup.lhs
tests/hlint.hs
```

One that jumps out at me is `Internal`

since it likely doesn’t depend on anything. We’ll start there.

## Internal

Looking at the top gives a hint for what we’re in for

```
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Data.Fold.Internal
( SnocList(..)
, SnocList1(..)
, List1(..)
, Maybe'(..), maybe'
, Pair'(..)
, N(..)
, Tree(..)
, Tree1(..)
, An(..)
, Box(..)
) where
```

This module seems to be mostly a bunch of (presumably useful) data types + their instances for `Foldable`

, `Functor`

, and `Traversable`

. Since all 3 of these are simple enough you can actually just derive them I’ll elide them in most cases.

First up is `SnocList`

, if the name didn’t give it away it is a backwards list (snoc is cons backwards)

```
data SnocList a = Snoc (SnocList a) a | Nil
deriving (Eq,Ord,Show,Read,Typeable,Data)
```

Then we have the boilerplatey instances for `Functor`

and `Foldable`

. What’s a bit odd is that both `foldl`

and `foldMap`

are implemented where we only need `foldl`

. Presumably this is because just `foldMap`

gives worse performance but that’s a little disappointing.

Next is `SnocList1`

and `List1`

which are quite similar.

```
data SnocList1 a = Snoc1 (SnocList1 a) a | First a
deriving (Eq,Ord,Show,Read,Typeable,Data)
data List1 a = Cons1 a (List1 a) | Last a
```

If you’ve never seen this before, notice how instead of `Nil`

we have a constructor which requires an element. This means that no matter how we construct a list we need to supply at least element. Among other things this means that `head`

would be safe.

We also have a couple strict structures. Notice that these cannot be functors since they break `fmap f . fmap g = fmap (f . g)`

(why?). We have

```
data Maybe' a = Nothing' | Just' !a
data Pair' a b = Pair' !a !b
```

And we have the obvious instance for `Foldable Maybe'`

and `Monoid (a, b)`

. Now it may seem a little silly to define these types, but from experience I can say anything that makes strictness a bit more explicit is wonderfully helpful. Now we can just use `seq`

on a `Pair'`

and know that both components will be forced.

Next we define a type for trees. One thing I noticed was the docs mentioned that this type reflects the structure of a `foldMap`

```
data Tree a
= Zero
| One a
| Two (Tree a) (Tree a)
deriving (Eq,Ord,Show,Read,Typeable,Data)
```

When we `foldMap`

each `One`

should be an element of the original collection. From there we can `fmap`

with the `map`

part of `foldMap`

, and we can imagine traversing the tree and replacing `Two l r`

with `l <> r`

, each `Zero`

with `mempty`

, and each `One a`

with a.

So that’s rather nifty. On top of this we have `Foldable`

, `Traversable`

, and `Functor`

instances.

We also have `Tree1`

which is similar but elides the `Zero`

` data Tree1 a = Bin1 (Tree1 a) (Tree1 a) | Tip1 a`

As you’d expect, this implements the same type classes as `Tree`

.

Now is where things get a bit weird. First up is a type for reifying monoids using `reflection`

. I actually was thinking about doing a post on it and then I discovered Austin Seipp has done an outstanding one. So we have this `N`

type with the definition

```
newtype N a s = N { runN :: a }
deriving (Eq,Ord,Show,Read,Typeable,Data)
```

Now with reflection there are two key components, there’s the type class instance floating around and a fresh type `s`

that keys it. If we have `s`

then we can easily demand a specific instance with `reflect (Proxy :: Proxy s)`

. That’s exactly what we do here. We can create a monoid instance using this trick with

```
instance Reifies s (a -> a -> a, a) => Monoid (N a s) where
mempty = N $ snd $ reflect (Proxy :: Proxy s)
mappend (N a) (N b) = N $ fst (reflect (Proxy :: Proxy s)) a b
```

So at each point we use our `s`

to grab the tuple of monoid operations we expect to be around and use them in the obvious manner. The only reason I could imagine doing this is if we had a structure which we want to use as a monoid in a number of different ways. I suppose we also could have just passed the dictionary around but maybe this was extremely ugly. We shall see later I suppose.

Last comes two data types I do not understand at all. There’s `An`

and `Box`

. The look extremely boring.

```
data Box a = Box a
newtype An a = An a
```

Their instances are the same everywhere as well.. I have no clue what these are for. Grepping shows they are used though so hopefully this mystery will become clearer as we go.

## Class

Going in order of the module DAG gives us `Data.Fold.Class.hs`

. This exports two type classes and one function

```
module Data.Fold.Class
( Scan(..)
, Folding(..)
, beneath
) where
```

One thing that worries me a little is that this imports `Control.Lens`

which I don’t understand nearly as well as I’d like to.. We’ll see how this turns out.

Our first class is

```
class Choice p => Scan p where
prefix1 :: a -> p a b -> p a b
postfix1 :: p a b -> a -> p a b
run1 :: a -> p a b -> b
interspersing :: a -> p a b -> p a b
```

So right away we notice this is a subclass of `Choice`

which is in turn a subclass of `Profunctor`

. `Choice`

captures the ability to pull an `Either`

through our profunctor.

```
left' :: p a b -> p (Either a c) (Either b c)
right' :: p a b -> p (Either c a) (Either c b)
```

Note that we can’t do this with ordinary profunctors since we’d need a function from `Either a c -> a`

which isn’t complete.

Back to `Scan p`

. `Scan p`

takes a profunctor which apparently represents our folds. We then can prefix the input we supply, postfix the input we supply, and run our fold on a single element of input. This is a bit weird to me, I’m not sure if the intention is to write something like

```
foldList :: Scan p => [a] -> p a b -> b
foldList [x] = run1 x
foldList (x : xs) = foldList xs . prefix1 x
```

or something else entirely. Additionally this doesn’t really conform to my intuition of what a scan is. I’d expect a scan to produce all of the intermediate output involved in folding. At this point, with no instances in scope, it’s a little tricky to see what’s supposed to be happening here.

There are a bunch of default-signature based implementations of these methods if your type implements `Foldable`

. Since this is the next type class in the module let’s look at that and then skip back to the defaults.

```
class Scan p => Folding p where
prefix :: Foldable t => t a -> p a b -> p a b
prefixOf :: Fold s a -> s -> p a b -> p a b
postfix :: Foldable t => p a b -> t a -> p a b
postfixOf :: Fold s a -> p a b -> s -> p a b
run :: Foldable t => t a -> p a b -> b
runOf :: Fold s a -> s -> p a b -> b
filtering :: (a -> Bool) -> p a b -> p a b
```

At this point I looked at a few of the types and my first thought was “Oh dammit lens..” but it’s actually not so bad! The first thing to do is ignore the `*Of`

functions which work across lens’s `Fold`

type. There seems to be a nice pair for each “running” function where it can work across a `Foldable`

container or lens’s notion of a fold.

```
prefix :: Foldable t => t a -> p a b -> p a b
postfix :: Foldable t => p a b -> t a -> p a b
run :: Foldable t => t a -> p a b -> b
```

The first two functions let us create a new fold that will accept some input and supplement it with a bunch of other inputs. `prefix`

gives the supplemental input followed by the new input and `postfix`

does the reverse. We can actually supply input and run the whole thing with `run`

.

All of these are defined with `folded`

from lens which reifies a foldable container into a `Fold`

. so `foo = fooOf folded`

is the default implementation for all of these. Now for the corresponding fold functions I’m reading them as “If you give me a lens to treat `s`

as a container that I can get elements from and a fold, I’ll feed the elements of `s`

into the fold.”

The types are tricky, but this type class seems to capture what it means to run a fold across some type of structure.

Now that we’ve seen how `An`

comes in handy. It’s used as a single object `Foldable`

container. Since it’s newtyped, this should basically run the same as just passing a single element in.

```
prefix1 = prefix . An
run1 = run . An
postfix1 p = postfix p . An
```

So a `Scan`

here apparently means a fold over a single element at a time. Still not sure why this is deserving of the name `Scan`

but there you are.

Last but not least we have a notion of dragging a fold through an optic with `beneath`

.

```
beneath :: Profunctor p => Optic p Identity s t a b -> p a b -> p s t
beneath l f = runIdentity #. l (Identity #. f)
```

Those `#.`

’s are like `lmap`

s but only work when the function we apply is a “runtime identity”. Basically this means we should be able to tell whether or not we applied the function or just used `unsafeCoerce`

when running the code. Otherwise all we do is set up our fold `f`

to work across `Identity`

and feed it into the optic.

## Concrete Implementations

Now a lot of the rest of the code is implementing those two type classes we went over. To figure out where all these implementations are I just ran

```
~$ cabal repl
> :info Scan
....
instance Scan R1 -- Defined at src/Data/Fold/R1.hs:25:10
instance Scan R -- Defined at src/Data/Fold/R.hs:27:10
instance Scan M1 -- Defined at src/Data/Fold/M1.hs:25:10
instance Scan M -- Defined at src/Data/Fold/M.hs:33:10
instance Scan L1' -- Defined at src/Data/Fold/L1'.hs:24:10
instance Scan L1 -- Defined at src/Data/Fold/L1.hs:25:10
instance Scan L' -- Defined at src/Data/Fold/L'.hs:33:10
instance Scan L -- Defined at src/Data/Fold/L.hs:33:10
```

Looking at the names, I really don’t want to go through each of these with this much detail. Instead I’ll skip all the `*1`

’s and go over `R`

, `L'`

, and `M`

to get a nice sampling of the sort of folds we get.

### R.hs

Up first is `R.hs`

. This defines the first type for a fold we’ve seen.

` data R a b = forall r. R (r -> b) (a -> r -> r) r`

Reading this as “a right fold from `a`

to `b`

” we notice a few parts here. It looks like that existential `r`

encodes our fold’s inner state and `r -> b`

maps the current state into the result of the fold. That leaves `a -> r -> r`

as the stepping function. All in all this doesn’t look *too* different from

```
foldAndPresent :: (a -> r -> r) -> r -> (r -> b) -> [a] -> b
foldAndPresent f z p = p . foldr f z
```

The rest of this module is devoted to making a *lot* of instances for `R`

. Some of these are really uninteresting like `Bind`

, but quite a few are enlightening. To start with, `Profunctor`

.

```
instance Profunctor R where
dimap f g (R k h z) = R (g . k) (h . f) z
rmap g (R k h z) = R (g . k) h z
lmap f (R k h z) = R k (h . f) z
```

This should more or less by what you expect since it’s really the only the way to get the types to fit together. We fit the map from `b -> d`

onto the presentation piece of the fold and stick the map from `a -> c`

onto the stepper so it can take the new pieces of input.

Next we have the instance for `Choice`

.

```
instance Choice R where
left' (R k h z) = R (_Left %~ k) step (Left z) where
step (Left x) (Left y) = Left (h x y)
step (Right c) _ = Right c
step _ (Right c) = Right c
right' (R k h z) = R (_Right %~ k) step (Right z) where
step (Right x) (Right y) = Right (h x y)
step (Left c) _ = Left c
step _ (Left c) = Left c
```

This was slightly harder for me to read, but it helps to remember that here `_Left %~`

and `_Right %~`

are just mapping over the left and right sides of an `Either`

. That clears up the presentation bit. For the initial state, when we’re pulling our computation through the left side we wrap it in a `Left`

, when we’re pulling it through the right, we wrap it in `Right`

.

The interesting bit is the new `step`

function. It short circuits if either our state or our new value is the wrong side of an `Either`

otherwise it just applies our stepping function and wraps it back up as an `Either`

.

In addition to being a profunctor, `R`

is also a monad and comonad as well as a whole bunch of more finely grained classes built around those two. I’ll just show the `Monad`

`Applicative`

, and `Comonad`

instance here.

```
instance Applicative (R a) where
pure b = R (\() -> b) (\_ () -> ()) ()
R xf bxx xz <*> R ya byy yz = R
(\(Pair' x y) -> xf x $ ya y)
(\b ~(Pair' x y) -> Pair' (bxx b x) (byy b y))
(Pair' xz yz)
instance Comonad (R a) where
extract (R k _ z) = k z
duplicate (R k h z) = R (R k h) h z
instance Monad (R a) where
return b = R (\() -> b) (\_ () -> ()) ()
m >>= f = R (\xs a -> run xs (f a)) (:) [] <*> m
```

Looking at the `Comonad`

instance nesting a fold within a fold doesn’t change the accumulator, only the presentation. A nested fold is one that runs and returns a *new* fold which is identical except the starting state is the result of the old fold.

The `<*>`

operator here is kind of nifty. First off it zips both folds together using the strict `Pair'`

. Finally when we get to the presentation stage we map the final state for the left which gives us a function, and the final state for the right maps to its argument. Applying these two gives us our final result.

Notice that there’s some craziness happening with irrefutable patterns. When we call this function we won’t attempt to force the second argument until `bxx`

forces `x`

or `byy`

forces `y`

. This is important because it makes sure that `<*>`

preserves short circuiting.

The monad instance has a suitably boring `return`

and `>>=`

is a bit odd. We have one machine which accumulates all the elements it’s given in a list, this is an “identity fold” of sorts. From there our presentation function returns a lambda which expects an `a`

and runs `f a`

with all the input we’ve saved. We combine this with `m`

by running it in parallel with `<*>`

and feeding the result of `m`

back into the lambda generated by the right.

Now we’re finally in a position to define our `Scan`

and `Folding`

instances. Since the `Scan`

instance can be determined from the `Folding`

one I’ll show `Folding`

.

```
instance Folding R where
run t (R k h z) = k (foldr h z t)
prefix s = extend (run s)
postfix t s = run s (duplicate t)
runOf l s (R k h z) = k (foldrOf l h z s)
prefixOf l s = extend (runOf l s)
postfixOf l t s = runOf l s (duplicate t)
filtering p (R k h z) = R k (\a r -> if p a then h a r else r) z
```

It took some time, but I understand how this works! The first thing to notice is that actually running a fold just relies on the `foldr`

we have from `Foldable`

. Postfixing a fold is particularly slick with right folds. Remember that `z`

represents the accumulated state for the remainder of the items in our sequence.

Therefore, to postfix a number of elements all we need do is run the fold on the container we’re given and store the results as the new initial state. This is precisely what happens with `run s (duplicate t)`

.

Now `prefix`

is the inefficient one here. To prefix an element we want to change how presentation works. Instead of just using the default presentation function, we actually want to take the final state we get and run the fold *again* using this prefixing sequence and then presenting the result. For this we have another helpful comonandic function, `extend`

. This leaks because it holds on to the sequence a lot longer than it needs to.

The rest of these functions are basically the same thing except maybe postfixing (ha) a function with `Of`

here and there.

## L’.hs

Next up is (strict) left folds. As with right folds this module is just a data type and a bunch of instances for it.

` forall r. L' (r -> b) (r -> a -> r) r`

One thing that surprised me here was that our state `r`

isn’t stored strictly! That’s a bit odd but presumably there’s a good reason for this. Now all the instances for `L'`

are the same as those for `R`

up to isomorphism because the types are well.. isomorphic.

The real difference comes in the instances for `Scan`

and `Folding`

. Remember how `Folding R`

used `foldr`

, well here we just use `foldl'`

. This has the upshot that all the strictness and whatnot is handled entirely by the foldable instance!

```
instance Folding L' where
run t (L' k h z) = k $! foldl' h z t
prefix s = run s . duplicate
postfix t s = extend (run s) t
runOf l s (L' k h z) = k $! foldlOf' l h z s
prefixOf l s = runOf l s . duplicate
postfixOf l t s = extend (runOf l s) t
filtering p (L' k h z) = L' k (\r a -> if p a then h r a else r) z
```

So everywhere we had `foldr`

we have `foldl'`

. The other interesting switch is that our definitions of `prefix`

and `postfix`

are almost perfectly swapped! This actually makes perfect sense when you think about it. In a left fold the state is propagating from the beginning to the end versus a right fold where it propagates from the end to the beginning! So to prefix something when folding to the left we add it to the initial state and when postfixing we use the presentation function to take our final state and continue to fold with it.

If you check above, you’ll find this to be precisely the opposite of what we had for right folds and since they both have the same comonad instance, we can swap the two implementations.

In fact, having read the implementation for right folds I’m noticing that almost everything in this file is *so* close to what we had before. It really seems like there is a clever abstraction just waiting to break out.

## M.hs

Now that we’ve seen how left and right folds are more or less the same, let’s try something completely different! `M.hs`

captures the notion of a `foldMap`

and looks pretty different than what we’ve seen before.

First things first, here’s the type in question.

` data M a b = forall m. M (m -> b) (a -> m) (m -> m -> m) m`

We still have a presentation function `m -> b`

, and we still have an internal state `m`

. However, we also have a conversion function to map our inputted values onto the values we know how to fold together and we have a tensor operation `m -> m -> m`

.

Now as before we have a profunctor instance

```
instance Profunctor M where
dimap f g (M k h m e) = M (g.k) (h.f) m e
rmap g (M k h m e) = M (g.k) h m e
lmap f (M k h m e) = M k (h.f) m e
```

Which might start to look familiar from what we’ve seen so far. Next we have a `Choice`

instance which is still a little intimidating.

```
instance Choice M where
left' (M k h m z) = M (_Left %~ k) (_Left %~ h) step (Left z) where
step (Left x) (Left y) = Left (m x y)
step (Right c) _ = Right c
step _ (Right c) = Right c
right' (M k h m z) = M (_Right %~ k) (_Right %~ h) step (Right z) where
step (Right x) (Right y) = Right (m x y)
step (Left c) _ = Left c
step _ (Left c) = Left c
```

As before we use prisms and `%~`

to drag our presentation and conversion functions into `Either`

, similarly our starting state is wrapped in the appropriate constructor and we define a new stepping function with similar characteristic’s to what we’ve seen before.

As before, we’ve got a wonderful world of monads and comonads to dive into now. We’ll start with monads here to mix it up.

```
instance Applicative (M a) where
pure b = M (\() -> b) (\_ -> ()) (\() () -> ()) ()
M xf bx xx xz <*> M ya by yy yz = M
(\(Pair' x y) -> xf x $ ya y)
(\b -> Pair' (bx b) (by b))
(\(Pair' x1 y1) (Pair' x2 y2) -> Pair' (xx x1 x2) (yy y1 y2))
(Pair' xz yz)
instance Monad (M a) where
return = pure
m >>= f = M (\xs a -> run xs (f a)) One Two Zero <*> m
```

Our `return`

/`pure`

just instantiates a trivial fold that consumes `()`

s and outputs the value we gave it. For `<*>`

we run both machines strictly next to each other and apply the final result of one to the final result of the other.

Bind creates a new fold that creates a tree. This tree contains every input fed to it as it’s folding and stores each merge a node in the tree. While we run this, we also run the original `m`

we were given. Finally, when we reach the end, we apply `f`

to the result of `m`

and run this over the tree we’ve created which is foldable. If you remember back to the comment of `Tree a`

capturing `foldMap`

this is what was meant by it: we’re using a tree to suspend a `foldMap`

until we’re in a position to run it.

Now for comonad.

```
instance Comonad (M a) where
extract (M k _ _ z) = k z
duplicate (M k h m z) = M (\n -> M (k . m n) h m z) h m z
```

We can be pleasantly surprised that most of this code is the same. Extraction grabs our current state and presents it. Duplication creates a fold which will run and return a new fold. This new fold has the same initial state as the original fold, but when it goes to present its results it will merge it with the final state of the outer fold. This is very different from before and I suspect it will significantly impact our `Folding`

instance.

```
instance Folding M where
run s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> k $ runN (foldMap (N #. h) s :: N m s)
prefix s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMap (N #. h) s :: N m s) of
x -> M (\y -> k (m x y)) h m z
postfix (M k h m (z :: m)) s = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMap (N #. h) s :: N m s) of
y -> M (\x -> k (m x y)) h m z
filtering p (M k h m z) = M k (\a -> if p a then h a else z) m z
```

This was a little intimidating so I took the liberty of ignoring `*Of`

functions which are pretty much the same as what we have here.

To run a fold we use `foldMap`

, but `foldMap`

wants to work over monoids and we only have `z`

and `m`

. To promote this to a type class we use `reify`

and `N`

. Remember `N`

from way back when? It’s the data type that uses reflection to yank a tuple out of our context and treat it as a monoid instance. In all of this code we use `reify`

to introduce a tuple to our environment and `N`

as a pseudo-monoid that uses `m`

and `z`

.

with this in mind, this code uses `N #. h`

which uses the normal conversion function to introduce something into the `N`

monoid. Then `foldMap`

takes care of the rest and all we need do is call `runN`

to extract the results.

`prefix`

and `postfix`

are actually markedly similar. They both start by running the fold over the supplied structure which reduces it to an `m`

. From there, we create a new fold which is identical in all respects except the presentation function. The new presentation function uses `m`

to combine the pre/post-fixed result with the new result. If we’re postfixing, the postfixed result is on the right, if we’re prefixing, the left.

What’s particularly stunning is that neither of these leak! We don’t need to hold onto the structure in our new fold so we can prefix and postfix in constant memory.

## Fold.hs

Now that we’ve gone through a bunch of instances of `Folding`

and `Scanning`

, we’re in a position to actually look at what `Data.Fold`

exports.

```
module Data.Fold
( Scan(..)
, Folding(..)
, beneath
, L1(..) -- lazy Mealy machine
, L1'(..) -- strict Mealy machine
, M1(..) -- semigroup reducer
, R1(..) -- reversed lazy Mealy machine
, L(..) -- lazy Moore machine
, L'(..) -- strict Moore machine
, M(..) -- monoidal reducer
, R(..) -- reversed lazy Moore machine
, AsRM1(..)
, AsL1'(..)
, AsRM(..)
, AsL'(..)
) where
```

So aside from the folds we’ve examined before, there are 4 new classes, `AsRM[1]`

, and `AsL[1]'`

. We’ll look at the non-1 versions.

```
class AsRM1 p => AsRM p where
asM :: p a b -> M a b
asR :: p a b -> R a b
```

So this class covers the class of `p`

’s that know how to convert themselves to middle and right folds. Most of these instances are what you’d expect if you’ve ever done the “write `foldl`

as `foldr`

” trick or similar shenanigans.

For `M`

```
instance AsRM M where
asR (M k h m z) = R k (m.h) z
asM = id
```

`asM`

is trivially identity and since `m`

is expected to be associative we don’t really care that `R`

is going to associate it strictly to the right. We just glue `h`

onto the front to map the next piece of input into something we know how to merge.

Next is `R`

```
instance AsRM R where
asM (R k h z) = M (\f -> k (f z)) h (.) id
asR = id
```

For right folds we do something a bit different. We transform each value into a function of type `m -> m`

which is the back half of a folding function. We can compose these associatively with `.`

since they are just functions. Finally, when we need to present this, we apply this giant pipeline to the initial state and present the result. Notice here how we took a nonassociative function and bludgeoned it into associativity by partially applying it.

For `L'`

we do something similar

```
instance AsRM L' where
asR (L' k h z) = R (\f -> k (f z)) (\b g x -> g $! h x b) id
asM = asM . asR
```

We once again build up a pipeline of functions to make everything associative and apply it at the end. We can’t just use `.`

though for composition because we need to force intermediate results. That’s why you see `\b g x -> g $! h x b`

, it’s just strict composition.

It makes sense that we’d bundle right and monoidal folds together because every right fold can be converted to a monoidal and every monoidal fold to a right. That means that every time we can satisfy one of these functions we can build the second.

This isn’t the case for left folds because we can’t convert a monoidal or right fold to a left one. For the people who are dubious of this, `foldl`

doesn’t let us capture the same amount of laziness we need. I forgot about this too and subsequently hung my machine trying to prove Edward Kmett wrong.

This means that the `AsL'`

is a fairly boring class,

```
class (AsRM p, AsL1' p) => AsL' p where
asL' :: p a b -> L' a b
instance AsL' L where
asL' (L k h z) = L' (\(Box r) -> k r) (\(Box r) a -> Box (h r a)) (Box z)
```

Now we finally see the point of `Box`

, it’s designed to stubbornly block attempts at making its contents strict. You can see this because all the instance for `L`

does is wrap everything in `Box`

es! Since `L'`

is the same as `L`

with some extra `seq`

s, we can use `Box`

to nullify those attempts at strictness and give us a normal left fold.

That’s it! We’re done!

## Wrap Up

Now that we’ve gone through a few concrete implementations and the overall structures in this package hopefully this has come together for you. I must say, I’m really quite surprised at how effectively comonadic operations can capture compositional folds. I’m certainly going to make an effort to use this package or Gabriel’s foldl a bit more in my random “tiny Haskell utility programs”.

If you’re as entranced by these nice little folding libraries as I am, I’d recommend

Trivia fact: this is the longest article out of all 52 posts on Code & Co.

*Update: I decided it might be helpful to write some utility folds for folds. I figured this might be interesting to some.*

<script type="text/javascript">
var disqus_shortname = 'codeco';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the

comments powered by Disqus.</noscript>

comments powered by