{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Polytropos.Optics (
fieldLens
, ctorOptic
) where
import Optics.Core
import Polytropos
import Polytropos.Core
import GHC.TypeLits
import GHC.Records
import Unsafe.Coerce
import Data.Functor.Identity
fieldLens :: forall n r a. FieldIndex n r a => Field n -> LensVL (Record r) (Record r) a a
fieldLens :: forall (n :: Symbol) (r :: Row) a.
FieldIndex n r a =>
Field n -> LensVL (Record r) (Record r) a a
fieldLens Field n
_ a -> f a
f (RowRep Rep Identity ()
r) =
(a -> RowRep Identity 'ProductRowT r ())
-> f a -> f (RowRep Identity 'ProductRowT r ())
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
a' -> Rep Identity () -> RowRep Identity 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep (Int -> Identity Any -> Rep Identity () -> Rep Identity ()
forall {k} (f :: * -> *) (a :: k).
Int -> f Any -> Rep f a -> Rep f a
setFieldAt (forall {kn} k {ka} (n :: kn) (row :: k) (a :: ka).
FieldIndex n row a =>
Int
forall k {ka} (n :: Symbol) (row :: k) (a :: ka).
FieldIndex n row a =>
Int
fieldIndex @_ @n @r @a) (Any -> Identity Any
forall a. a -> Identity a
Identity (a -> Any
forall a b. a -> b
unsafeCoerce a
a')) Rep Identity ()
r))
(a -> f a
f (ZonkAny 0 -> a
forall a b. a -> b
unsafeCoerce (Identity (ZonkAny 0) -> ZonkAny 0
forall a. Identity a -> a
runIdentity (Int -> Rep Identity () -> Identity (ZonkAny 0)
forall {k} (f :: * -> *) (a :: k) x. Int -> Rep f a -> f x
fieldAt (forall {kn} k {ka} (n :: kn) (row :: k) (a :: ka).
FieldIndex n row a =>
Int
forall k {ka} (n :: Symbol) (row :: k) (a :: ka).
FieldIndex n row a =>
Int
fieldIndex @_ @n @r @a) Rep Identity ()
r))))
instance {-# OVERLAPPING #-} (KnownSymbol n, HasField n (Record r) field, FieldIndex n r field, a ~ field, b ~ field)
=> LabelOptic n A_Lens (Record r) (Record r) a b where
labelOptic :: Optic A_Lens NoIx (Record r) (Record r) a b
labelOptic = LensVL (Record r) (Record r) a b
-> Optic A_Lens NoIx (Record r) (Record r) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL (Field n -> LensVL (Record r) (Record r) a a
forall (n :: Symbol) (r :: Row) a.
FieldIndex n r a =>
Field n -> LensVL (Record r) (Record r) a a
fieldLens (forall (n :: Symbol). Field n
Field @n))
ctorOptic :: forall c s fs. ConstructorIndex c s => Field c -> Optic A_Prism NoIx (Variant s) (Variant s) (Record fs) (Record fs)
ctorOptic :: forall (c :: Symbol) (s :: SumRow) (fs :: Row).
ConstructorIndex c s =>
Field c
-> Optic
A_Prism NoIx (Variant s) (Variant s) (Record fs) (Record fs)
ctorOptic Field c
f = (Record fs -> Variant s)
-> (Variant s -> Maybe (Record fs))
-> Prism (Variant s) (Variant s) (Record fs) (Record fs)
forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (Field c -> Record fs -> Variant s
forall (n :: Symbol) (s :: SumRow) (fs :: Row).
ConstructorIndex n s =>
Field n -> Record fs -> Variant s
injectVariant Field c
f) Variant s -> Maybe (Record fs)
project
where
project :: Variant s -> Maybe (Record fs)
project :: Variant s -> Maybe (Record fs)
project (RowRep Rep Identity ()
r) = case Word -> Rep Identity () -> Maybe [Identity Any]
forall {k} (f :: * -> *) (a :: k). Word -> Rep f a -> Maybe [f Any]
projectRep (forall {kn} k (n :: kn) (row :: k). ConstructorIndex n row => Word
forall k (n :: Symbol) (row :: k). ConstructorIndex n row => Word
constructorIndex @_ @c @s) Rep Identity ()
r of
Just [Identity Any]
vals -> Record fs -> Maybe (Record fs)
forall a. a -> Maybe a
Just (Rep Identity () -> Record fs
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep ([Identity Any] -> Rep Identity ()
forall {k} (f :: * -> *) (a :: k). [f Any] -> Rep f a
productRep [Identity Any]
vals))
Maybe [Identity Any]
Nothing -> Maybe (Record fs)
forall a. Maybe a
Nothing