Assume the following newtype
is defined:
newtype A a = A a
And there is a function:
f :: A a -> A a
Now suppose I define another newtype
, which contains A a
:
newtype B a = B (A a)
And then I'd like to define a function fb
which operates on B a
but just uses f
:
fb :: B a -> B a
fb (B x) = B (f x)
Now this is quite inconvenient since I have to unwrap and wrap the value inside an element of type B a
. This won't be that bad if I only had to define one such a fb
but if there are a lot of them this becomes quite tedious.
I'd be nice if there would be a type-class with a function:
(<$$>) :: k a -> k b -> h (k a) -> h (k b)
So that fb
can be rewritten as:
fb = (f <$$>)
Maybe such an abstraction already exists, but I cannot find it.
One solution is to use the newtype-generics package, in particular the over
function:
{-# LANGUAGE DeriveGeneric #-}
import Control.Newtype (Newtype, over)
import GHC.Generics
newtype A a = A a
newtype B a = B (A a) deriving (Generic)
instance Newtype (B a)
f :: A a -> A a
f = undefined
fb :: B a -> B a
fb = over B f
Notice that over
requires the outer B
constructor as a parameter, not only the function f
.