module Indigo.Internal.Field
( AccessFieldC
, fetchField
, assignField
, FieldLens (..)
, flSFO
, HasField (..)
, fieldLensDeeper
, fieldLensADT
) where
import Data.Vinyl (RElem)
import Data.Vinyl.TypeLevel (RIndex)
import Data.Vinyl.Lens (rget, rput)
import GHC.TypeLits (KnownSymbol)
import Indigo.Lorentz
import Indigo.Prelude
import qualified Lorentz.ADT as L
import Michelson.Typed.Haskell.Instr.Product
(GetFieldType, InstrSetFieldC, InstrGetFieldC, ConstructorFieldNames)
type AccessFieldC a name =
RElem name (ConstructorFieldNames a) (RIndex name (ConstructorFieldNames a))
fetchField
:: forall a name f proxy . AccessFieldC a name
=> proxy name -> Rec f (ConstructorFieldNames a) -> f name
fetchField :: proxy name -> Rec f (ConstructorFieldNames a) -> f name
fetchField _ = forall (rs :: [Symbol]) (f :: Symbol -> *)
(record :: (Symbol -> *) -> [Symbol] -> *).
(RecElem record name name rs rs (RIndex name rs),
RecElemFCtx record f) =>
record f rs -> f name
forall k (r :: k) (rs :: [k]) (f :: k -> *)
(record :: (k -> *) -> [k] -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
record f rs -> f r
rget @name
assignField
:: forall a name f proxy . AccessFieldC a name
=> proxy name -> f name -> Rec f (ConstructorFieldNames a) -> Rec f (ConstructorFieldNames a)
assignField :: proxy name
-> f name
-> Rec f (ConstructorFieldNames a)
-> Rec f (ConstructorFieldNames a)
assignField _ = forall (rs :: [Symbol]) (record :: (Symbol -> *) -> [Symbol] -> *)
(f :: Symbol -> *).
(RecElem record name name rs rs (RIndex name rs),
RecElemFCtx record f) =>
f name -> record f rs -> record f rs
forall k (r :: k) (rs :: [k]) (record :: (k -> *) -> [k] -> *)
(f :: k -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
f r -> record f rs -> record f rs
rput @name
data FieldLens dt fname ftype where
TargetField
:: ( InstrGetFieldC dt fname
, InstrSetFieldC dt fname
, GetFieldType dt fname ~ targetFType
, AccessFieldC dt fname
)
=> Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
DeeperField
:: ( AccessFieldC dt fname
, InstrSetFieldC dt fname
, HasField (GetFieldType dt fname) targetFName targetFType
)
=> Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
flSFO :: FieldLens dt fname ftype -> StoreFieldOps dt fname ftype
flSFO :: FieldLens dt fname ftype -> StoreFieldOps dt fname ftype
flSFO (TargetField _ sfo :: StoreFieldOps dt fname ftype
sfo) = StoreFieldOps dt fname ftype
sfo
flSFO (DeeperField _ sfo :: StoreFieldOps dt fname ftype
sfo) = StoreFieldOps dt fname ftype
sfo
class (KnownValue ftype, KnownValue dt) => HasField dt fname ftype | dt fname -> ftype where
fieldLens :: FieldLens dt fname ftype
fieldLensADT
:: forall dt targetFName targetFType fname .
( InstrGetFieldC dt fname
, InstrSetFieldC dt fname
, GetFieldType dt fname ~ targetFType
, AccessFieldC dt fname
)
=> Label fname -> FieldLens dt targetFName targetFType
fieldLensADT :: Label fname -> FieldLens dt targetFName targetFType
fieldLensADT lb :: Label fname
lb =
let sfo :: StoreFieldOps dt fname targetFType
sfo = forall ftype.
HasFieldOfType dt fname ftype =>
StoreFieldOps dt fname ftype
forall dt (fname :: Symbol) ftype.
HasFieldOfType dt fname ftype =>
StoreFieldOps dt fname ftype
storeFieldOpsADT @dt @fname in
Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
forall dt (fname :: Symbol) targetFType (targetFName :: Symbol).
(InstrGetFieldC dt fname, InstrSetFieldC dt fname,
GetFieldType dt fname ~ targetFType, AccessFieldC dt fname) =>
Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
TargetField Label fname
lb (StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType)
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
forall a b. (a -> b) -> a -> b
$ $WStoreFieldOps :: forall store (fname :: Symbol) ftype.
(forall (s :: [*]). Label fname -> (store : s) :-> (ftype : s))
-> (forall (s :: [*]).
Label fname -> (ftype : store : s) :-> (store : s))
-> StoreFieldOps store fname ftype
StoreFieldOps
{ sopToField :: forall (s :: [*]).
Label targetFName -> (dt : s) :-> (targetFType : s)
sopToField = \_ -> StoreFieldOps dt fname targetFType
-> Label fname -> (dt : s) :-> (targetFType : s)
forall store (fname :: Symbol) ftype.
StoreFieldOps store fname ftype
-> forall (s :: [*]). Label fname -> (store : s) :-> (ftype : s)
sopToField StoreFieldOps dt fname targetFType
sfo Label fname
lb
, sopSetField :: forall (s :: [*]).
Label targetFName -> (targetFType : dt : s) :-> (dt : s)
sopSetField = \_ -> StoreFieldOps dt fname targetFType
-> Label fname -> (targetFType : dt : s) :-> (dt : s)
forall store (fname :: Symbol) ftype.
StoreFieldOps store fname ftype
-> forall (s :: [*]).
Label fname -> (ftype : store : s) :-> (store : s)
sopSetField StoreFieldOps dt fname targetFType
sfo Label fname
lb
}
fieldLensDeeper
:: forall dt targetName targetType fname .
( AccessFieldC dt fname
, L.HasFieldOfType dt fname (GetFieldType dt fname)
, HasField (GetFieldType dt fname) targetName targetType
)
=> Label fname
-> FieldLens dt targetName targetType
fieldLensDeeper :: Label fname -> FieldLens dt targetName targetType
fieldLensDeeper lb :: Label fname
lb =
Label fname
-> StoreFieldOps dt targetName targetType
-> FieldLens dt targetName targetType
forall dt (fname :: Symbol) (targetFName :: Symbol) targetFType.
(AccessFieldC dt fname, InstrSetFieldC dt fname,
HasField (GetFieldType dt fname) targetFName targetFType) =>
Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
DeeperField Label fname
lb (Label fname
-> StoreFieldOps
dt
fname
(LnrFieldType
(LNRequireFound fname dt (GLookupNamed fname (Rep dt))))
-> StoreFieldOps
(LnrFieldType
(LNRequireFound fname dt (GLookupNamed fname (Rep dt))))
targetName
targetType
-> StoreFieldOps dt targetName targetType
forall (nameInStore :: Symbol) store substore
(nameInSubstore :: Symbol) field.
Label nameInStore
-> StoreFieldOps store nameInStore substore
-> StoreFieldOps substore nameInSubstore field
-> StoreFieldOps store nameInSubstore field
composeStoreFieldOps Label fname
lb (forall dt (fname :: Symbol) ftype.
HasFieldOfType dt fname ftype =>
StoreFieldOps dt fname ftype
forall (fname :: Symbol) ftype.
HasFieldOfType dt fname ftype =>
StoreFieldOps dt fname ftype
storeFieldOpsADT @dt) (FieldLens
(LnrFieldType
(LNRequireFound fname dt (GLookupNamed fname (Rep dt))))
targetName
targetType
-> StoreFieldOps
(LnrFieldType
(LNRequireFound fname dt (GLookupNamed fname (Rep dt))))
targetName
targetType
forall dt (fname :: Symbol) ftype.
FieldLens dt fname ftype -> StoreFieldOps dt fname ftype
flSFO FieldLens
(LnrFieldType
(LNRequireFound fname dt (GLookupNamed fname (Rep dt))))
targetName
targetType
forall dt (fname :: Symbol) ftype.
HasField dt fname ftype =>
FieldLens dt fname ftype
fieldLens))
instance {-# OVERLAPPABLE #-}
( InstrSetFieldC dt fname
, InstrGetFieldC dt fname
, GetFieldType dt fname ~ ftype
, AccessFieldC dt fname
, KnownSymbol fname
, KnownValue ftype, KnownValue dt
)
=> HasField dt fname ftype where
fieldLens :: FieldLens dt fname ftype
fieldLens = Label fname
-> StoreFieldOps dt fname ftype -> FieldLens dt fname ftype
forall dt (fname :: Symbol) targetFType (targetFName :: Symbol).
(InstrGetFieldC dt fname, InstrSetFieldC dt fname,
GetFieldType dt fname ~ targetFType, AccessFieldC dt fname) =>
Label fname
-> StoreFieldOps dt targetFName targetFType
-> FieldLens dt targetFName targetFType
TargetField (KnownSymbol fname => Label fname
forall (name :: Symbol). KnownSymbol name => Label name
Label @fname) StoreFieldOps dt fname ftype
forall dt (fname :: Symbol) ftype.
HasFieldOfType dt fname ftype =>
StoreFieldOps dt fname ftype
storeFieldOpsADT