[Haskell-cafe] generalized newtype deriving allows the definition
of otherwise undefinable functions
Wolfgang Jeltsch
g9ks157k at acme.softbase.org
Fri Mar 12 04:22:39 EST 2010
Am Donnerstag, 11. März 2010 00:37:18 schrieb wren ng thornton:
> Wolfgang Jeltsch wrote:
> > Hello,
> >
> > some time ago, it was pointed out that generalized newtype deriving could
> > be used to circumvent module borders. Now, I found out that generalized
> > newtype deriving can even be used to define functions that would be
> > impossible to define otherwise. To me, this is surprising since I thought
> > that generalized newtype deriving was only intended to save the
> > programmer from writing boilerplate code, not to extend expressiveness.
>
> Let's dig down and figure out the problem. When you annotate the type
> "Wrapped a" with "deriving (Iso a)" what are you saying? You're saying
> that the compiler should derive an instance (Iso a (Wrapped a)). Well,
> that instance gives you the method instance conv :: forall f. f a -> f
> (Wrapped a). The funny thing is that the only implementation for
> ---something like--- that type would be fmap Wrap.
If the parameter of f is contravariant then we would need a “contraMap”, not
an fmap. Example:
> newtype CoFun a b = CoFun (b -> a)
>
> class ContraFunctor f where
>
> contraMap :: (a -> b) -> f b -> f a
>
> instance ContraFunctor (CoFun a) where
>
> contraMap f (CoFun g) = CoFun (g . f)
>
> coFun :: CoFun Int Char
> coFun = CoFun ord
>
> directlyConverted :: CoFun Int (Wrapped Char)
> directlyConverted = conv coFun
>
> manuallyConverted :: CoFun Int (Wrapped Char)
> manuallyConverted = contraMap unwrap coFun
Here, unwrap is the inverse of Wrap.
Let us look at the Set example from John Meacham. Set is a (covariant)
functor, not a contravariant functor. However, it isn’t a functor from and to
the category of Haskell types and functions but the category of types of class
Ord and Ord homomorphisms (functions that respect ordering). The problem in
John Meacham’s Set example is that Down doesn’t preserve ordering. If conv is
used with a newtype wrapper constructor that does preserve ordering, this is
the same as applying Set.map or Set.mapMonotonic.
Best wishes,
Wolfgang
More information about the Haskell-Cafe
mailing list