Search code examples
haskellnewtype

Mapping the value inside a newtype


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.


Solution

  • 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.