{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Polytropos.Microlens
(
fieldLens
, AllFieldsAre
) where
import Data.Kind (Constraint, Type)
import Data.Functor.Identity (Identity (..))
import GHC.Exts (toList)
import Lens.Micro (Lens')
import Lens.Micro.Internal (Each (..))
import Polytropos (Record, Field (..))
import Polytropos.Core (FieldIndex (..), Row, Pair (..), fieldAt,
noInlineUnsafeCo, productRep, repVals, setFieldAt,
RowRep (..))
type family AllFieldsAre (a :: Type) (r :: Row) :: Constraint where
AllFieldsAre _ '[] = ()
AllFieldsAre a ((n ':= a) ': rest) = AllFieldsAre a rest
instance AllFieldsAre a r
=> Each (Record ((n ':= a) ': r)) (Record ((n ':= a) ': r)) a a where
each :: Traversal (Record ((n ':= a) : r)) (Record ((n ':= a) : r)) a a
each a -> f a
f (RowRep Rep Identity ()
rep) =
Rep Identity () -> Record ((n ':= a) : r)
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep (Rep Identity () -> Record ((n ':= a) : r))
-> ([Identity a] -> Rep Identity ())
-> [Identity a]
-> Record ((n ':= a) : r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Identity Any] -> Rep Identity ()
forall {k} (f :: * -> *) (a :: k). [f Any] -> Rep f a
productRep ([Identity Any] -> Rep Identity ())
-> ([Identity a] -> [Identity Any])
-> [Identity a]
-> Rep Identity ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Identity a] -> [Identity Any]
forall a b. a -> b
noInlineUnsafeCo
([Identity a] -> Record ((n ':= a) : r))
-> f [Identity a] -> f (Record ((n ':= a) : r))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Identity Any -> f (Identity a))
-> [Identity Any] -> f [Identity a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (\(Identity Any
x) -> a -> Identity a
forall a. a -> Identity a
Identity (a -> Identity a) -> f a -> f (Identity a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f (Any -> a
forall a b. a -> b
noInlineUnsafeCo Any
x))
(SmallArray (Identity Any) -> [Item (SmallArray (Identity Any))]
forall l. IsList l => l -> [Item l]
toList (Rep Identity () -> SmallArray (Identity Any)
forall {k} (f :: * -> *) (a :: k). Rep f a -> SmallArray (f Any)
repVals Rep Identity ()
rep))
{-# INLINE each #-}
fieldLens :: forall n r a. FieldIndex n r a => Field n -> Lens' (Record r) a
fieldLens :: forall (n :: Symbol) (r :: Row) a.
FieldIndex n r a =>
Field n -> Lens' (Record r) a
fieldLens Field n
_ a -> f a
f (RowRep Rep Identity ()
rep) =
(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
noInlineUnsafeCo a
a'))
Rep Identity ()
rep))
(a -> f a
f (ZonkAny 0 -> a
forall a b. a -> b
noInlineUnsafeCo (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 ()
rep))))
{-# INLINE fieldLens #-}