{-# 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