Working on a project and trying to write longzip using an anamorphism. I'm having some trouble writing a coalgebra for this use case. I've defined my anamorphism in terms of Fix
below:
-- Fixed point of a Functor
newtype Fix f = In (f (Fix f))
deriving instance (Eq (f (Fix f))) => Eq (Fix f)
out :: Fix f -> f (Fix f)
out (In f) = f
-- Anamorphism
type Coalgebra f a = a -> f a
ana :: (Functor f) => Coalgebra f a -> a -> Fix f
ana f = In . fmap (ana f) . f
This is the definition for ana
derived from "reversing the arrows" of cata:
-- Catamorphism
type Algebra f a = f a -> a
cata :: (Functor f) => Algebra f a -> Fix f -> a
cata f = f . fmap (cata f) . out
I've seen zip
written using a version of ana that is obviously defined differently (takes a predicate as a parameter):
zip2 = ana unsp fin
where
fin (as,bs) = (as==[]) || (bs ==[])
unsp ((a:as), (b:bs)) = ((a,b),(as,bs))
(Taken from https://en.wikipedia.org/wiki/Anamorphism)
But I'm unsure how to move forward using the version of ana
defined above, particularly in regards to writing a Coalgebra
of type a -> fa
. Like, would it have to take the two list parameters to zip
and combine them into a single a
?
First off, give yourself a starting point. Write down what you're going to do:
You know
zip
has to be implemented as a call toana
, so what remains is figuring out the seed and the coalgebra. It should be fairly clear the seed needs to containx
andy
. It doesn't seem like any further information should be necessary, so let's just assume the seed will be(x, y)
until/unless it poses a problem. That's enough information to pin down the types for this first try:I feel like this is the step you've missed: writing down what you're trying to do and following the types to pin down what you need. The rest of this is sort of trivial if you've ever seen any implementation of
zip
. It's a matter of writing down the most boring thing that type-checks (paying close attention to the difference betweenList
andListF
in the type). I strongly recommend you stop reading here and give it a try yourself. There isn't much else I can say that's actually helpful for learning how to think about this.If you really have no idea at all:
It really is what you'd expect if you've ever seen an implementation of
zip
before, with the necessary noise to make it type-check aroundFix
. Let's give it a spin:Yep. Behaving as expected. It seems the two lists were sufficient as the seed, and all is well.