{-# LANGUAGE GADTs #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE TypeOperators #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Generics.Internal.VL.Iso -- Copyright : (C) 2017 Csongor Kiss -- License : BSD3 -- Maintainer : Csongor Kiss -- Stability : experimental -- Portability : non-portable -- -- Internal lens helpers. Only exported for Haddock -- ----------------------------------------------------------------------------- module Data.Generics.Internal.VL.Iso where import Data.Profunctor (Profunctor(..)) import GHC.Generics import Data.Generics.Internal.GenericN (Rec (..)) type Iso' s a = forall p f. (Profunctor p, Functor f) => p a (f a) -> p s (f s) type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t) -- | A type and its generic representation are isomorphic repIso :: (Generic a, Generic b) => Iso a b (Rep a x) (Rep b x) repIso = iso from to -- | 'M1' is just a wrapper around `f p` mIso :: Iso (M1 i c f p) (M1 i c g p) (f p) (g p) mIso = iso unM1 M1 kIso :: Iso (K1 r a p) (K1 r b p) a b kIso = iso unK1 K1 recIso :: Iso (Rec r a p) (Rec r b p) a b recIso = iso (unK1 . unRec) (Rec . K1) prodIso :: Iso ((a :*: b) x) ((a' :*: b') x) (a x, b x) (a' x, b' x) prodIso = iso (\(a :*: b) -> (a, b)) (\(a, b) -> (a :*: b)) iso :: (s -> a) -> (b -> t) -> Iso s t a b iso sa bt = dimap sa (fmap bt) {-# INLINE iso #-}