Consider the following type:
data SomeType m a = SomeType (m Integer) [a]
We can easily make that type an instance of Functor with the following code:
instance Functor (SomeType m) where
fmap f (SomeType m lst) = SomeType m (map f lst)
However, if instead the params of the SomeType type were swapped:
data SomeType2 a m = SomeType2 (m Integer) [a]
Then the above instance definition doesn’t work.
Is there some way of making SomeType2 an instance of Functor? If not, are there any up and coming additions to haskell/ghc that would make it possible?
Biased am I, but I think this is a great opportunity to make use of Control.Newtype, a little piece of kit that’s a mere “cabal install newtype” away.
Here’s the deal. You want to flip around type constructors to get your hands on functoriality (for example) in a different parameter. Define a newtype
and add it to the
Newtypeclass thusThe
Newtypeclass is just a directory mapping newtypes to their unvarnished equivalents, providing handy kit, e.g.op Flipis the inverse ofFlip: you don’t need to remember what you called it.For the problem in question, we can now do stuff like this:
That’s a two parameter datatype which happens to be functorial in both parameters. (Probably, we should make it an instance of a Bifunctor class, but anyway…) We can make it a
Functortwice over: once for the last parameter……and once for the first:
where
under p fis a neat way to sayop p . f . p.I tell you no lies: let us try.
and then we get
In these circumstances, there really are many ways the same thing can be seen as a
Functor, so it’s right that we have to make some noise to say which way we mean. But the noise isn’t all that much if you’re systematic about it.