[Haskell-cafe] Partial instance of a class

Michael Walker mike at barrucadu.co.uk
Tue Feb 27 14:06:03 UTC 2018


On 27 February 2018 at 13:28, MarLinn <monkleyon at gmail.com> wrote:
> It feels like the underlying problem is the same as with arr: At first there
> seems to be no way to lift functions into the structure. And we don't want
> to create two separate types because the whole idea of PU is to make pairs
> of related picklers and unpicklers composable.

For my own learning, a while ago I implemented a little
encoding/decoding library, with the encoders based on contravariant
functors.  I started with a type which I called `Codec a`, which
contained both an encoding and a decoding function.  As you did, I
quickly found that this makes many typeclass instances impossible.
So, like in Tom's reply, I instead added a more generic `Codec' a b`
type, which separates the encoding and decoding parameters.  I kept
`Codec a` as a type synonym for `Codec' a a`.

I found the change to make the resulting code much nicer to implement
and to use, even though it would be possible for a user to construct
an encoder/decoder pair which decodes to a different type than what
they started with.

In fact, after another round of type parameter introduction
(abstracting over the concrete type of the encoded value: bytestrings
and bytestring builders in `Codec'`, but type parameters in the yet
more general type), I discovered a very natural separation between my
"codecs" and combinators for composing them.

So in this case, I suppose the moral of the story is that having a
type parameter which is both covariant and contravariant is not that
useful, and you can always just constrain the type variables to be the
same where you need to anyway.

The code is here: https://github.com/barrucadu/wheat

Michael Walker (http://www.barrucadu.co.uk)

More information about the Haskell-Cafe mailing list