{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE ViewPatterns #-} module Composite.Lens.Extra ( rlensS, rlensS', rlensS'', ) where import Composite.Record (Rec, Record, getVal, (:->) (Val)) import qualified Control.Lens as L import Data.Functor.Contravariant (Contravariant (contramap)) import qualified Data.Vinyl as Vinyl import Data.Vinyl.TypeLevel (RIndex) -- | Type changing lens over a `Record` field. -- -- @since 0.0.1.0 rlensS :: forall p p' s s' a b g rs rs'. ( (p ~ (s :-> a)), (p' ~ (s' :-> b)), Vinyl.RecElem Rec (s :-> a) (s' :-> b) rs rs' (RIndex (s :-> a) rs), Functor g ) => (a -> g b) -> Record rs -> g (Record rs') rlensS f = Vinyl.rlens' @p @p' $ \(L.Identity (getVal -> a)) -> L.Identity . Val <$> f a -- | Type changing lens over a `Rec f` (Covariant). -- -- @since 0.0.1.0 rlensS' :: forall p p' s s' a b f g rs rs'. ( (p ~ (s :-> a)), (p' ~ (s' :-> b)), Vinyl.RecElem Rec (s :-> a) (s' :-> b) rs rs' (Data.Vinyl.TypeLevel.RIndex (s :-> a) rs), Functor f, Functor g ) => (f a -> g (f b)) -> Rec f rs -> g (Rec f rs') rlensS' f = Vinyl.rlens' @p @p' $ \(fmap getVal -> a) -> fmap Val <$> f a -- | Type changing lens over a `Rec f` (Contravariant). -- -- @since 0.0.1.0 rlensS'' :: forall p p' s s' a b f g rs rs'. ( (p ~ (s :-> a)), (p' ~ (s' :-> b)), Vinyl.RecElem Rec (s :-> a) (s' :-> b) rs rs' (Data.Vinyl.TypeLevel.RIndex (s :-> a) rs), Contravariant f, Functor g ) => (f a -> g (f b)) -> Rec f rs -> g (Rec f rs') rlensS'' f = Vinyl.rlens' @p @p' $ \(contramap Val -> a) -> contramap getVal <$> f a