superrecord-0.3.0.0: Supercharged anonymous records

Safe HaskellNone
LanguageHaskell2010

SuperRecord

Contents

Synopsis

Basics

data label := value infix 6 Source #

Field named l labels value of type t adapted from the awesome labels package. Example: (#name := "Chris") :: ("name" := String)

Constructors

KnownSymbol label => (FldProxy label) := !value infix 6 

Instances

KnownSymbol name => FromNative * (S1 (MetaSel (Just Symbol name) p s l) (Rec0 t)) ((:) * ((:=) name t) ([] *)) Source # 

Methods

fromNative' :: (* ': (name := t)) [*] x -> Rec lts

(RecEq rts (RemoveAccessTo l lts), Has * l rts v, Eq v) => RecEq rts ((:) * ((:=) l t) lts) Source # 

Methods

recEq :: Rec rts -> Rec rts -> Proxy [*] ((* ': (l := t)) lts) -> Bool Source #

(KnownSymbol l, RecApply rts (RemoveAccessTo l lts) c, Has * l rts v, c v) => RecApply rts ((:) * ((:=) l t) lts) c Source # 

Methods

recApply :: (forall a. Dict (c a) -> String -> a -> b -> b) -> Rec rts -> Proxy [*] ((* ': (l := t)) lts) -> b -> b Source #

Eq value => Eq ((:=) label value) Source # 

Methods

(==) :: (label := value) -> (label := value) -> Bool #

(/=) :: (label := value) -> (label := value) -> Bool #

Ord value => Ord ((:=) label value) Source # 

Methods

compare :: (label := value) -> (label := value) -> Ordering #

(<) :: (label := value) -> (label := value) -> Bool #

(<=) :: (label := value) -> (label := value) -> Bool #

(>) :: (label := value) -> (label := value) -> Bool #

(>=) :: (label := value) -> (label := value) -> Bool #

max :: (label := value) -> (label := value) -> label := value #

min :: (label := value) -> (label := value) -> label := value #

Show t => Show ((:=) l t) Source # 

Methods

showsPrec :: Int -> (l := t) -> ShowS #

show :: (l := t) -> String #

showList :: [l := t] -> ShowS #

(KnownSymbol l, FromJSON t, RecJsonParse lts, (~) Nat (RecSize lts) s, KnownNat s, KeyDoesNotExist l lts) => RecJsonParse ((:) * ((:=) l t) lts) Source # 

Methods

recJsonParse :: Int -> Object -> Parser (Rec ((* ': (l := t)) lts)) Source #

(KnownSymbol l, RecKeys lts) => RecKeys ((:) * ((:=) l t) lts) Source # 

Associated Types

type RecKeysT ((:) * ((:=) l t) lts :: [*]) :: [Symbol] Source #

Methods

recFields :: t ((* ': (l := t)) lts) -> RecFields (RecKeysT ((* ': (l := t)) lts)) Source #

(Has * l rts v, NFData v, RecNfData (RemoveAccessTo l lts) rts) => RecNfData ((:) * ((:=) l t) lts) rts Source # 

Methods

recNfData :: Proxy [*] ((* ': (l := t)) lts) -> Rec rts -> () Source #

(Has * l rts t, Has * l lts t, RecCopy (RemoveAccessTo l ((:) * ((:=) l t) pts)) lts rts) => RecCopy ((:) * ((:=) l t) pts) lts rts Source # 

Methods

recCopyInto :: Proxy [*] ((* ': (l := t)) pts) -> Rec lts -> Proxy [*] rts -> SmallMutableArray# RealWorld (Any *) -> State# RealWorld -> State# RealWorld

type RecKeysT ((:) * ((:=) l t) lts) Source # 
type RecKeysT ((:) * ((:=) l t) lts) = (:) Symbol l (RecKeysT lts)

type Record lts = Rec (Sort lts) Source #

The core record type. Prefer this type when manually writing type signatures

rnil :: Rec '[] Source #

An empty record

rcons :: forall l t lts s. (RecSize lts ~ s, KnownNat s, KnownNat (RecVecIdxPos l (Sort ((l := t) ': lts))), KeyDoesNotExist l lts, RecCopy lts lts (Sort ((l := t) ': lts))) => (l := t) -> Rec lts -> Rec (Sort ((l := t) ': lts)) Source #

Prepend a record entry to a record Rec

(&) :: forall l t lts s. (RecSize lts ~ s, KnownNat s, KnownNat (RecVecIdxPos l (Sort ((l := t) ': lts))), KeyDoesNotExist l lts, RecCopy lts lts (Sort ((l := t) ': lts))) => (l := t) -> Rec lts -> Rec (Sort ((l := t) ': lts)) infixr 5 Source #

Alias for rcons

fld :: FldProxy l -> FldProxy l Source #

Helper function to allow to clearing specify unknown IsLabel cases

type Has l lts v = (RecTy l lts ~ v, KnownNat (RecSize lts), KnownNat (RecVecIdxPos l lts)) Source #

Require a record to contain a label

type family HasOf (req :: [*]) (lts :: [*]) :: Constraint where ... Source #

Require a record to contain at least the listed labels

Equations

HasOf ((l := t) ': req) lts = (Has l lts t, HasOf req lts) 
HasOf '[] lts = True ~ True 

get :: forall l v lts. Has l lts v => FldProxy l -> Rec lts -> v Source #

Get an existing record field

(&.) :: forall l v lts. Has l lts v => Rec lts -> FldProxy l -> v infixl 3 Source #

Alias for get

set :: forall l v lts. Has l lts v => FldProxy l -> v -> Rec lts -> Rec lts Source #

Update an existing record field

modify :: forall l v lts. Has l lts v => FldProxy l -> (v -> v) -> Rec lts -> Rec lts Source #

Update an existing record field

getPath :: RecApplyPath k x => k -> Rec x -> RecDeepTy k x Source #

Perform a deep read. This is somewhat similar to using (&.), but is useful when you want to share a RecPath between getPath, modifyPath and/or setPath

setPath :: RecApplyPath k x => k -> RecDeepTy k x -> Rec x -> Rec x Source #

Perform a deep update, setting the key along the path to the desired value

modifyPath :: RecApplyPath k x => k -> (RecDeepTy k x -> RecDeepTy k x) -> Rec x -> Rec x Source #

Perform a deep update, transforming the value at the final key

class RecApplyPath p x Source #

Minimal complete definition

setPath', getPath'

Instances

(Has * l lts t, (~) * t (RecDeepTy * (FldProxy l) lts)) => RecApplyPath (FldProxy l) lts Source # 

Methods

setPath' :: FldProxy l -> (RecDeepTy * (FldProxy l) lts -> RecDeepTy * (FldProxy l) lts) -> Rec lts -> Rec lts

getPath' :: FldProxy l -> Rec lts -> RecDeepTy * (FldProxy l) lts

((~) * (RecDeepTy * ((:&) l more) lts) (RecDeepTy * more rts), (~) * (RecTy * l lts) (Rec rts), Has * l lts v, (~) * v (Rec rts), RecApplyPath more rts) => RecApplyPath ((:&) l more) lts Source # 

Methods

setPath' :: (l :& more) -> (RecDeepTy * (l :& more) lts -> RecDeepTy * (l :& more) lts) -> Rec lts -> Rec lts

getPath' :: (l :& more) -> Rec lts -> RecDeepTy * (l :& more) lts

data lbl :& more infixr 8 Source #

Constructor for field accessor paths

Instances

((~) * (RecDeepTy * ((:&) l more) lts) (RecDeepTy * more rts), (~) * (RecTy * l lts) (Rec rts), Has * l lts v, (~) * v (Rec rts), RecApplyPath more rts) => RecApplyPath ((:&) l more) lts Source # 

Methods

setPath' :: (l :& more) -> (RecDeepTy * (l :& more) lts -> RecDeepTy * (l :& more) lts) -> Rec lts -> Rec lts

getPath' :: (l :& more) -> Rec lts -> RecDeepTy * (l :& more) lts

(&:) :: FldProxy q -> more -> q :& more infixr 8 Source #

Constructor for field accessor paths

(&:-) :: FldProxy q -> FldProxy r -> q :& FldProxy r infixr 8 Source #

Specialized version of (&:) to help writing the last piece of the path w/o confusing the type checker

combine :: forall lhs rhs. (KnownNat (RecSize lhs), KnownNat (RecSize rhs), KnownNat (RecSize lhs + RecSize rhs), RecCopy lhs lhs (Sort (RecAppend lhs rhs)), RecCopy rhs rhs (Sort (RecAppend lhs rhs))) => Rec lhs -> Rec rhs -> Rec (Sort (RecAppend lhs rhs)) Source #

Combine two records

(++:) :: forall lhs rhs. (KnownNat (RecSize lhs), KnownNat (RecSize rhs), KnownNat (RecSize lhs + RecSize rhs), RecCopy lhs lhs (Sort (RecAppend lhs rhs)), RecCopy rhs rhs (Sort (RecAppend lhs rhs))) => Rec lhs -> Rec rhs -> Rec (Sort (RecAppend lhs rhs)) Source #

Alias for combine

type RecAppend lhs rhs = RecAppendH lhs rhs rhs '[] Source #

Reflection

reflectRec :: forall c r lts. RecApply lts lts c => Proxy c -> (forall a. c a => String -> a -> r) -> Rec lts -> [r] Source #

Apply a function to each key element pair for a record

reflectRecFold :: forall c r lts. RecApply lts lts c => Proxy c -> (forall a. c a => String -> a -> r -> r) -> Rec lts -> r -> r Source #

Fold over all elements of a record

class RecApply rts lts c where Source #

Machinery needed to implement reflectRec

Minimal complete definition

recApply

Methods

recApply :: (forall a. Dict (c a) -> String -> a -> b -> b) -> Rec rts -> Proxy lts -> b -> b Source #

Instances

RecApply rts ([] *) c Source # 

Methods

recApply :: (forall a. Dict (c a) -> String -> a -> b -> b) -> Rec rts -> Proxy [*] [*] -> b -> b Source #

(KnownSymbol l, RecApply rts (RemoveAccessTo l lts) c, Has * l rts v, c v) => RecApply rts ((:) * ((:=) l t) lts) c Source # 

Methods

recApply :: (forall a. Dict (c a) -> String -> a -> b -> b) -> Rec rts -> Proxy [*] ((* ': (l := t)) lts) -> b -> b Source #

Native type interop

class FromNative a lts | a -> lts Source #

Conversion helper to bring a Haskell type to a record. Note that the native Haskell type must be an instance of Generic

Minimal complete definition

fromNative'

Instances

(FromNative * l lhs, FromNative * r rhs, (~) [*] lts (Sort (RecAppend lhs rhs)), RecCopy lhs lhs lts, RecCopy rhs rhs lts, KnownNat (RecSize lhs), KnownNat (RecSize rhs), KnownNat ((+) (RecSize lhs) (RecSize rhs))) => FromNative * ((:*:) l r) lts Source # 

Methods

fromNative' :: lts x -> Rec lts

FromNative * cs lts => FromNative * (D1 m cs) lts Source # 

Methods

fromNative' :: lts x -> Rec lts

FromNative * cs lts => FromNative * (C1 m cs) lts Source # 

Methods

fromNative' :: lts x -> Rec lts

KnownSymbol name => FromNative * (S1 (MetaSel (Just Symbol name) p s l) (Rec0 t)) ((:) * ((:=) name t) ([] *)) Source # 

Methods

fromNative' :: (* ': (name := t)) [*] x -> Rec lts

fromNative :: (Generic a, FromNative (Rep a) lts) => a -> Rec lts Source #

Convert a native Haskell type to a record

class ToNative a lts | a -> lts Source #

Conversion helper to bring a record back into a Haskell type. Note that the native Haskell type must be an instance of Generic

Minimal complete definition

toNative'

Instances

(ToNative * l lts, ToNative * r lts) => ToNative * ((:*:) l r) lts Source # 

Methods

toNative' :: Rec lts -> lts x

ToNative * cs lts => ToNative * (D1 m cs) lts Source # 

Methods

toNative' :: Rec lts -> lts x

ToNative * cs lts => ToNative * (C1 m cs) lts Source # 

Methods

toNative' :: Rec lts -> lts x

Has * name lts t => ToNative * (S1 (MetaSel (Just Symbol name) p s l) (Rec0 t)) lts Source # 

Methods

toNative' :: Rec lts -> lts x

toNative :: (Generic a, ToNative (Rep a) lts) => Rec lts -> a Source #

Convert a record to a native Haskell type

MTL interop

asksR :: (Has lbl lts v, MonadReader (Rec lts) m) => FldProxy lbl -> m v Source #

Like asks for MonadReader, but you provide a record field you would like to read from your environment

asksRP :: (RecApplyPath k x, MonadReader (Rec x) m) => k -> m (RecDeepTy k x) Source #

Like asks for MonadReader, but you provide a record field you would like to read from your environment

getsR :: (Has lbl lts v, MonadState (Rec lts) m) => FldProxy lbl -> m v Source #

Like gets for MonadState, but you provide a record field you would like to read from your environment

setsR :: (Has lbl lts v, MonadState (Rec lts) m) => FldProxy lbl -> v -> m () Source #

Similar to put for MonadState, but you only set a single record field

modifiesR :: (Has lbl lts v, MonadState (Rec lts) m) => FldProxy lbl -> (v -> v) -> m () Source #

Similar to modify for MonadState, but you update a single record field

getsRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> m (RecDeepTy k x) Source #

Similar to gets for MonadState, but allows getting a value along a RecPath

setsRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> RecDeepTy k x -> m () Source #

Similar to put for MonadState, but you only set a single record field

modifiesRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> (RecDeepTy k x -> RecDeepTy k x) -> m () Source #

Similar to modify for MonadState, but you update a single record field

Lens interop

lens :: Has l lts v => FldProxy l -> Lens (Rec lts) (Rec lts) v v Source #

Convert a field label to a lens

Machinery

data Rec lts Source #

Internal record type. When manually writing an explicit type signature for a record, use Record instead. For abstract type signatures Rec will work well.

Instances

RecEq lts lts => Eq (Rec lts) Source # 

Methods

(==) :: Rec lts -> Rec lts -> Bool #

(/=) :: Rec lts -> Rec lts -> Bool #

RecApply lts lts Show => Show (Rec lts) Source # 

Methods

showsPrec :: Int -> Rec lts -> ShowS #

show :: Rec lts -> String #

showList :: [Rec lts] -> ShowS #

RecApply lts lts ToJSON => ToJSON (Rec lts) Source # 

Methods

toJSON :: Rec lts -> Value #

toEncoding :: Rec lts -> Encoding #

toJSONList :: [Rec lts] -> Value #

toEncodingList :: [Rec lts] -> Encoding #

((~) Nat (RecSize lts) s, KnownNat s, RecJsonParse lts) => FromJSON (Rec lts) Source # 

Methods

parseJSON :: Value -> Parser (Rec lts) #

parseJSONList :: Value -> Parser [Rec lts] #

RecNfData lts lts => NFData (Rec lts) Source # 

Methods

rnf :: Rec lts -> () #

class RecCopy pts lts rts Source #

Minimal complete definition

recCopyInto

Instances

RecCopy ([] *) lts rts Source # 
(Has * l rts t, Has * l lts t, RecCopy (RemoveAccessTo l ((:) * ((:=) l t) pts)) lts rts) => RecCopy ((:) * ((:=) l t) pts) lts rts Source # 

Methods

recCopyInto :: Proxy [*] ((* ': (l := t)) pts) -> Rec lts -> Proxy [*] rts -> SmallMutableArray# RealWorld (Any *) -> State# RealWorld -> State# RealWorld

type family RecTyIdxH (i :: Nat) (l :: Symbol) (lts :: [*]) :: Nat where ... Source #

Equations

RecTyIdxH idx l ((l := t) ': lts) = idx 
RecTyIdxH idx m ((l := t) ': lts) = RecTyIdxH (1 + idx) m lts 
RecTyIdxH idx m '[] = TypeError (Text "Could not find label " :<>: Text m) 

showRec :: forall lts. RecApply lts lts Show => Rec lts -> [(String, String)] Source #

Convert all elements of a record to a String

class RecKeys lts where Source #

Get keys of a record on value and type level

Minimal complete definition

recFields

Associated Types

type RecKeysT lts :: [Symbol] Source #

Methods

recFields :: t lts -> RecFields (RecKeysT lts) Source #

Instances

RecKeys ([] *) Source # 

Associated Types

type RecKeysT ([] * :: [*]) :: [Symbol] Source #

Methods

recFields :: t [*] -> RecFields (RecKeysT [*]) Source #

(KnownSymbol l, RecKeys lts) => RecKeys ((:) * ((:=) l t) lts) Source # 

Associated Types

type RecKeysT ((:) * ((:=) l t) lts :: [*]) :: [Symbol] Source #

Methods

recFields :: t ((* ': (l := t)) lts) -> RecFields (RecKeysT ((* ': (l := t)) lts)) Source #

recKeys :: forall t lts. RecKeys lts => t lts -> [String] Source #

class RecEq rts lts where Source #

Machinery to implement equality

Minimal complete definition

recEq

Methods

recEq :: Rec rts -> Rec rts -> Proxy lts -> Bool Source #

Instances

RecEq rts ([] *) Source # 

Methods

recEq :: Rec rts -> Rec rts -> Proxy [*] [*] -> Bool Source #

(RecEq rts (RemoveAccessTo l lts), Has * l rts v, Eq v) => RecEq rts ((:) * ((:=) l t) lts) Source # 

Methods

recEq :: Rec rts -> Rec rts -> Proxy [*] ((* ': (l := t)) lts) -> Bool Source #

recToValue :: forall lts. RecApply lts lts ToJSON => Rec lts -> Value Source #

recToEncoding :: forall lts. RecApply lts lts ToJSON => Rec lts -> Encoding Source #

recJsonParser :: forall lts s. (RecSize lts ~ s, KnownNat s, RecJsonParse lts) => Value -> Parser (Rec lts) Source #

class RecJsonParse lts where Source #

Machinery to implement parseJSON

Minimal complete definition

recJsonParse

Methods

recJsonParse :: Int -> Object -> Parser (Rec lts) Source #

Instances

RecJsonParse ([] *) Source # 

Methods

recJsonParse :: Int -> Object -> Parser (Rec [*]) Source #

(KnownSymbol l, FromJSON t, RecJsonParse lts, (~) Nat (RecSize lts) s, KnownNat s, KeyDoesNotExist l lts) => RecJsonParse ((:) * ((:=) l t) lts) Source # 

Methods

recJsonParse :: Int -> Object -> Parser (Rec ((* ': (l := t)) lts)) Source #

class RecNfData lts rts where Source #

Machinery for NFData

Minimal complete definition

recNfData

Methods

recNfData :: Proxy lts -> Rec rts -> () Source #

Instances

RecNfData ([] *) rts Source # 

Methods

recNfData :: Proxy [*] [*] -> Rec rts -> () Source #

(Has * l rts v, NFData v, RecNfData (RemoveAccessTo l lts) rts) => RecNfData ((:) * ((:=) l t) lts) rts Source # 

Methods

recNfData :: Proxy [*] ((* ': (l := t)) lts) -> Rec rts -> () Source #

type family RecSize (lts :: [*]) :: Nat where ... Source #

Equations

RecSize '[] = 0 
RecSize ((l := t) ': lts) = 1 + RecSize lts 

type family RemoveAccessTo (l :: Symbol) (lts :: [*]) :: [*] where ... Source #

Equations

RemoveAccessTo l ((l := t) ': lts) = RemoveAccessTo l lts 
RemoveAccessTo q ((l := t) ': lts) = (l := t) ': RemoveAccessTo l lts 
RemoveAccessTo q '[] = '[] 

data FldProxy t Source #

A proxy witness for a label. Very similar to Proxy, but needed to implement a non-orphan IsLabel instance

Constructors

FldProxy 

Instances

(~) Symbol l l' => IsLabel l (FldProxy l') Source # 

Methods

fromLabel :: Proxy# Symbol l -> FldProxy l' #

Eq (FldProxy t) Source # 

Methods

(==) :: FldProxy t -> FldProxy t -> Bool #

(/=) :: FldProxy t -> FldProxy t -> Bool #

Ord (FldProxy t) Source # 

Methods

compare :: FldProxy t -> FldProxy t -> Ordering #

(<) :: FldProxy t -> FldProxy t -> Bool #

(<=) :: FldProxy t -> FldProxy t -> Bool #

(>) :: FldProxy t -> FldProxy t -> Bool #

(>=) :: FldProxy t -> FldProxy t -> Bool #

max :: FldProxy t -> FldProxy t -> FldProxy t #

min :: FldProxy t -> FldProxy t -> FldProxy t #

Read (FldProxy t) Source # 
Show (FldProxy t) Source # 

Methods

showsPrec :: Int -> FldProxy t -> ShowS #

show :: FldProxy t -> String #

showList :: [FldProxy t] -> ShowS #

(Has * l lts t, (~) * t (RecDeepTy * (FldProxy l) lts)) => RecApplyPath (FldProxy l) lts Source # 

Methods

setPath' :: FldProxy l -> (RecDeepTy * (FldProxy l) lts -> RecDeepTy * (FldProxy l) lts) -> Rec lts -> Rec lts

getPath' :: FldProxy l -> Rec lts -> RecDeepTy * (FldProxy l) lts

type family RecDeepTy (ps :: r) (lts :: [*]) :: * where ... Source #

Equations

RecDeepTy (l :& more) ((l := Rec t) ': lts) = RecDeepTy more t 
RecDeepTy (l :& more) ((l := t) ': lts) = t 
RecDeepTy (l :& more) ((q := t) ': lts) = RecDeepTy (l :& more) lts 
RecDeepTy (FldProxy l) '[l := t] = t 
RecDeepTy l '[l := t] = t 

type family KeyDoesNotExist (l :: Symbol) (lts :: [*]) :: Constraint where ... Source #

Equations

KeyDoesNotExist l '[] = True ~ True 
KeyDoesNotExist l ((l := t) ': lts) = TypeError (Text "Duplicate key " :<>: Text l) 
KeyDoesNotExist q ((l := t) ': lts) = KeyDoesNotExist q lts