Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "compose" Iso's?

Here is my type:

newtype SaneDate = SaneDate UniversalTime
   deriving (Show, Eq, Typeable, Generic)
makeWrapped ''SaneDate

Now I need an iso with this type:

reprBuild :: Iso' (Maybe UniversalTime) (Fist SaneDate)

I did this:

reprBuild = iso
   (\ t -> First (SaneDate <$> t) )
   (\ sane_first -> fmap (^. _Wrapped) $ getFirst sane_first  )

But I have the impression I'm working extra-hard. Is there a (shorter) way of writing the reprBuild iso as a composition of things?

like image 211
dsign Avatar asked Mar 04 '26 08:03

dsign


1 Answers

The mapping combinator lets you lift an Iso over any functor (in this case the Maybe functor):

reprBuild' :: Iso' (Maybe UniversalTime) (Maybe SaneDate)
reprBuild' = mapping _Unwrapped

We can also use the fact that First has a Wrapped instance to get the iso you want:

reprBuild :: Iso' (Maybe UniversalTime) (First SaneDate)
reprBuild = mapping _Unwrapped . _Unwrapped

You can also use the coercion isomorphism: coerced but this will only work over newtype wrappers and needs ghc >= 7.10.

like image 113
cchalmers Avatar answered Mar 05 '26 23:03

cchalmers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!