-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Supercharged anonymous records -- -- Anonymous records with various useful utilities @package superrecord @version 0.5.0.0 module SuperRecord -- | Field named l labels value of type t adapted from -- the awesome labels package. Example: (#name := "Chris") :: -- ("name" := String) data label (:=) value (:=) :: FldProxy label -> !value -> (:=) label value -- | The core record type. Prefer this type when manually writing type -- signatures type Record lts = Rec (Sort lts) -- | An empty record rnil :: Rec '[] -- | Prepend a record entry to a record Rec rcons :: forall l t lts s sortedLts. (RecSize lts ~ s, sortedLts ~ Sort ((l := t) : lts), KnownNat s, KnownNat (RecVecIdxPos l sortedLts), KeyDoesNotExist l lts, RecCopy lts lts sortedLts) => l := t -> Rec lts -> Rec sortedLts -- | Alias for rcons (&) :: forall l t lts s sortedLts. (RecSize lts ~ s, sortedLts ~ Sort ((l := t) : lts), KnownNat s, KnownNat (RecVecIdxPos l sortedLts), KeyDoesNotExist l lts, RecCopy lts lts sortedLts) => l := t -> Rec lts -> Rec sortedLts infixr 5 & -- | Helper function to allow to clearing specify unknown IsLabel -- cases fld :: FldProxy l -> FldProxy l -- | Require a record to contain a label type Has l lts v = (RecTy l lts ~ v, KnownNat (RecSize lts), KnownNat (RecVecIdxPos l lts)) -- | Require a record to contain at least the listed labels -- | Get an existing record field get :: forall l v lts. (Has l lts v) => FldProxy l -> Rec lts -> v -- | Alias for get (&.) :: forall l v lts. (Has l lts v) => Rec lts -> FldProxy l -> v infixl 3 &. -- | Update an existing record field set :: forall l v lts. (Has l lts v) => FldProxy l -> v -> Rec lts -> Rec lts -- | Update an existing record field modify :: forall l v lts. (Has l lts v) => FldProxy l -> (v -> v) -> Rec lts -> Rec lts -- | 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 getPath :: RecApplyPath k x => k -> Rec x -> RecDeepTy k x -- | Perform a deep update, setting the key along the path to the desired -- value setPath :: RecApplyPath k x => k -> RecDeepTy k x -> Rec x -> Rec x -- | Perform a deep update, transforming the value at the final key modifyPath :: RecApplyPath k x => k -> (RecDeepTy k x -> RecDeepTy k x) -> Rec x -> Rec x class RecApplyPath p x -- | Constructor for field accessor paths data lbl (:&) more -- | Constructor for field accessor paths (&:) :: FldProxy q -> more -> q :& more infixr 8 &: -- | Specialized version of (&:) to help writing the last piece of the -- path w/o confusing the type checker (&:-) :: FldProxy q -> FldProxy r -> q :& FldProxy r infixr 8 &:- -- | Combine two records combine :: forall lhs rhs sortRes. (KnownNat (RecSize lhs), KnownNat (RecSize rhs), KnownNat (RecSize lhs + RecSize rhs), sortRes ~ Sort (RecAppend lhs rhs), RecCopy lhs lhs sortRes, RecCopy rhs rhs sortRes) => Rec lhs -> Rec rhs -> Rec sortRes -- | Alias for combine (++:) :: forall lhs rhs sortRes. (KnownNat (RecSize lhs), KnownNat (RecSize rhs), KnownNat (RecSize lhs + RecSize rhs), sortRes ~ Sort (RecAppend lhs rhs), RecCopy lhs lhs sortRes, RecCopy rhs rhs sortRes) => Rec lhs -> Rec rhs -> Rec sortRes type RecAppend lhs rhs = RecAppendH lhs rhs rhs '[] -- | Apply a function to each key element pair for a record reflectRec :: forall c r lts. (RecApply lts lts c) => Proxy c -> (forall a. c a => String -> a -> r) -> Rec lts -> [r] -- | Fold over all elements of 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 -- | Machinery needed to implement reflectRec class RecApply (rts :: [*]) (lts :: [*]) c recApply :: RecApply rts lts c => (forall a. Dict (c a) -> String -> a -> b -> b) -> Rec rts -> Proxy lts -> b -> b -- | Conversion helper to bring a Haskell type to a record. Note that the -- native Haskell type must be an instance of Generic class FromNative a lts | a -> lts -- | Convert a native Haskell type to a record fromNative :: (Generic a, FromNative (Rep a) lts) => a -> Rec lts -- | Conversion helper to bring a record back into a Haskell type. Note -- that the native Haskell type must be an instance of Generic class ToNative a lts -- | Convert a record to a native Haskell type toNative :: (Generic a, ToNative (Rep a) lts) => Rec lts -> a -- | Like asks for MonadReader, but you provide a record -- field you would like to read from your environment asksR :: (Has lbl lts v, MonadReader (Rec lts) m) => FldProxy lbl -> m v -- | 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) -- | Like gets for MonadState, 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 -- | Similar to put for MonadState, but you only set a -- single record field setsR :: (Has lbl lts v, MonadState (Rec lts) m) => FldProxy lbl -> v -> m () -- | Similar to modify for MonadState, but you update a -- single record field modifiesR :: (Has lbl lts v, MonadState (Rec lts) m) => FldProxy lbl -> (v -> v) -> m () -- | Similar to gets for MonadState, but allows getting a -- value along a RecPath getsRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> m (RecDeepTy k x) -- | Similar to put for MonadState, but you only set a -- single record field setsRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> RecDeepTy k x -> m () -- | Similar to modify for MonadState, but you update a -- single record field modifiesRP :: (RecApplyPath k x, MonadState (Rec x) m) => k -> (RecDeepTy k x -> RecDeepTy k x) -> m () -- | Convert a field label to a lens lens :: Has l lts v => FldProxy l -> Lens (Rec lts) (Rec lts) v v -- | Internal record type. When manually writing an explicit type signature -- for a record, use Record instead. For abstract type signatures -- Rec will work well. data Rec (lts :: [*]) class RecCopy (pts :: [*]) (lts :: [*]) (rts :: [*]) -- | Convert all elements of a record to a String showRec :: forall lts. (RecApply lts lts Show) => Rec lts -> [(String, String)] -- | Get keys of a record on value and type level class RecKeys (lts :: [*]) where { type family RecKeysT lts :: [Symbol]; } recFields :: RecKeys lts => t lts -> RecFields (RecKeysT lts) recKeys :: forall t (lts :: [*]). RecKeys lts => t lts -> [String] -- | Machinery to implement equality class RecEq (rts :: [*]) (lts :: [*]) recEq :: RecEq rts lts => Rec rts -> Rec rts -> Proxy lts -> Bool recToValue :: forall lts. (RecApply lts lts ToJSON) => Rec lts -> Value recToEncoding :: forall lts. (RecApply lts lts ToJSON) => Rec lts -> Encoding recJsonParser :: forall lts s. (RecSize lts ~ s, KnownNat s, RecJsonParse lts) => Value -> Parser (Rec lts) -- | Machinery to implement parseJSON class RecJsonParse (lts :: [*]) recJsonParse :: RecJsonParse lts => Int -> Object -> Parser (Rec lts) -- | Machinery for NFData class RecNfData (lts :: [*]) (rts :: [*]) recNfData :: RecNfData lts rts => Proxy lts -> Rec rts -> () -- | A proxy witness for a label. Very similar to Proxy, but needed -- to implement a non-orphan IsLabel instance data FldProxy (t :: Symbol) FldProxy :: FldProxy -- | Sort a list of fields using merge sort, alias to FieldListSort type Sort xs = FieldListSort xs instance forall k (cs :: k -> *) (lts :: [*]) (m :: GHC.Generics.Meta). SuperRecord.ToNative cs lts => SuperRecord.ToNative (GHC.Generics.D1 m cs) lts instance forall k (cs :: k -> *) (lts :: [*]) (m :: GHC.Generics.Meta). SuperRecord.ToNative cs lts => SuperRecord.ToNative (GHC.Generics.C1 m cs) lts instance SuperRecord.Has name lts t => SuperRecord.ToNative (GHC.Generics.S1 ('GHC.Generics.MetaSel ('GHC.Base.Just name) p s l) (GHC.Generics.Rec0 t)) lts instance forall k (l :: k -> *) (lts :: [*]) (r :: k -> *). (SuperRecord.ToNative l lts, SuperRecord.ToNative r lts) => SuperRecord.ToNative (l GHC.Generics.:*: r) lts instance forall k (cs :: k -> *) (lts :: [*]) (m :: GHC.Generics.Meta). SuperRecord.FromNative cs lts => SuperRecord.FromNative (GHC.Generics.D1 m cs) lts instance forall k (cs :: k -> *) (lts :: [*]) (m :: GHC.Generics.Meta). SuperRecord.FromNative cs lts => SuperRecord.FromNative (GHC.Generics.C1 m cs) lts instance GHC.TypeLits.KnownSymbol name => SuperRecord.FromNative (GHC.Generics.S1 ('GHC.Generics.MetaSel ('GHC.Base.Just name) p s l) (GHC.Generics.Rec0 t)) '[name SuperRecord.Field.:= t] instance forall k (l :: k -> *) (lhs :: [*]) (r :: k -> *) (rhs :: [*]) (lts :: [*]). (SuperRecord.FromNative l lhs, SuperRecord.FromNative r rhs, lts ~ SuperRecord.Sort (SuperRecord.RecAppend lhs rhs), SuperRecord.RecCopy lhs lhs lts, SuperRecord.RecCopy rhs rhs lts, GHC.TypeNats.KnownNat (SuperRecord.RecSize lhs), GHC.TypeNats.KnownNat (SuperRecord.RecSize rhs), GHC.TypeNats.KnownNat (SuperRecord.RecSize lhs GHC.TypeNats.+ SuperRecord.RecSize rhs)) => SuperRecord.FromNative (l GHC.Generics.:*: r) lts instance SuperRecord.RecNfData lts lts => Control.DeepSeq.NFData (SuperRecord.Rec lts) instance SuperRecord.RecNfData '[] rts instance (SuperRecord.Has l rts v, Control.DeepSeq.NFData v, SuperRecord.RecNfData (SuperRecord.RemoveAccessTo l lts) rts) => SuperRecord.RecNfData ((l SuperRecord.Field.:= t) : lts) rts instance (SuperRecord.RecSize lts ~ s, GHC.TypeNats.KnownNat s, SuperRecord.RecJsonParse lts) => Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Rec lts) instance SuperRecord.RecJsonParse '[] instance (GHC.TypeLits.KnownSymbol l, Data.Aeson.Types.FromJSON.FromJSON t, SuperRecord.RecJsonParse lts, SuperRecord.RecSize lts ~ s, GHC.TypeNats.KnownNat s, SuperRecord.KeyDoesNotExist l lts) => SuperRecord.RecJsonParse ((l SuperRecord.Field.:= t) : lts) instance (SuperRecord.Has l rts t, SuperRecord.Has l lts t, SuperRecord.RecCopy (SuperRecord.RemoveAccessTo l ((l SuperRecord.Field.:= t) : pts)) lts rts) => SuperRecord.RecCopy ((l SuperRecord.Field.:= t) : pts) lts rts instance (GHC.TypeLits.KnownSymbol l, SuperRecord.RecApply rts (SuperRecord.RemoveAccessTo l lts) c, SuperRecord.Has l rts v, c v) => SuperRecord.RecApply rts ((l SuperRecord.Field.:= t) : lts) c instance (SuperRecord.RecEq rts (SuperRecord.RemoveAccessTo l lts), SuperRecord.Has l rts v, GHC.Classes.Eq v) => SuperRecord.RecEq rts ((l SuperRecord.Field.:= t) : lts) instance SuperRecord.RecEq lts lts => GHC.Classes.Eq (SuperRecord.Rec lts) instance SuperRecord.RecEq rts '[] instance SuperRecord.RecApply lts lts GHC.Show.Show => GHC.Show.Show (SuperRecord.Rec lts) instance SuperRecord.RecApply lts lts Data.Aeson.Types.ToJSON.ToJSON => Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Rec lts) instance SuperRecord.RecApply rts '[] c instance SuperRecord.RecKeys '[] instance (GHC.TypeLits.KnownSymbol l, SuperRecord.RecKeys lts) => SuperRecord.RecKeys ((l SuperRecord.Field.:= t) : lts) instance (SuperRecord.Has l lts t, t ~ SuperRecord.RecDeepTy (SuperRecord.Field.FldProxy l) lts) => SuperRecord.RecApplyPath (SuperRecord.Field.FldProxy l) lts instance (SuperRecord.RecDeepTy (l SuperRecord.:& more) lts ~ SuperRecord.RecDeepTy more rts, SuperRecord.RecTy l lts ~ SuperRecord.Rec rts, SuperRecord.Has l lts v, v ~ SuperRecord.Rec rts, SuperRecord.RecApplyPath more rts) => SuperRecord.RecApplyPath (l SuperRecord.:& more) lts instance SuperRecord.RecCopy '[] lts rts module SuperRecord.Variant -- | A variant is used to express that a values type is of any of the types -- tracked in the type level list. data Variant (opts :: [*]) type VariantPos a opts = VariantPosHelper 1 a opts -- | An empty Variant, equivalent to `()` emptyVariant :: Variant '[] -- | Convert a usual Haskell type into a Variant. It's very useful -- to provide type signatures for the Variants. toVariant :: forall opts a pos. (KnownNat pos, VariantPos a opts ~ pos, VariantMember a opts) => a -> Variant opts -- | Convert a Variant back to a usual Haskell type, returning -- Nothing if the variant is not of the desired type. fromVariant :: forall opts a pos. (KnownNat pos, VariantPos a opts ~ pos, VariantMember a opts) => Variant opts -> Maybe a data VariantMatch r ts [VariantCase] :: (t -> r) -> VariantMatch r ts -> VariantMatch r (t : ts) [VariantEnd] :: VariantMatch r '[] [VariantWildCard] :: r -> VariantMatch r ts -- | Pattern matching helper with totality check. Note that the performance -- of this pattern match is roughly like a normal pattern match. (See -- benchmarks) class VariantMatcher r opts variantMatch :: VariantMatcher r opts => Variant opts -> VariantMatch r opts -> r -- | Remove an option from a Variant shrinkVariant :: Variant (t : ts) -> Variant ts -- | Add an option to a Variant extendVariant :: Variant ts -> Variant (t : ts) instance SuperRecord.Variant.VariantMatcher r ts => SuperRecord.Variant.VariantMatcher r (t : ts) instance SuperRecord.Variant.VariantMatcher r '[] instance Control.DeepSeq.NFData (SuperRecord.Variant.Variant '[]) instance (Control.DeepSeq.NFData t, Control.DeepSeq.NFData (SuperRecord.Variant.Variant ts)) => Control.DeepSeq.NFData (SuperRecord.Variant.Variant (t : ts)) instance Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Variant '[]) instance (Data.Aeson.Types.ToJSON.ToJSON t, Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Variant ts)) => Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Variant (t : ts)) instance Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Variant '[]) instance (Data.Aeson.Types.FromJSON.FromJSON t, Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Variant ts)) => Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Variant (t : ts)) instance GHC.Show.Show (SuperRecord.Variant.Variant '[]) instance (GHC.Show.Show t, GHC.Show.Show (SuperRecord.Variant.Variant ts)) => GHC.Show.Show (SuperRecord.Variant.Variant (t : ts)) instance GHC.Classes.Eq (SuperRecord.Variant.Variant '[]) instance (GHC.Classes.Eq t, GHC.Classes.Eq (SuperRecord.Variant.Variant ts)) => GHC.Classes.Eq (SuperRecord.Variant.Variant (t : ts)) instance GHC.Classes.Ord (SuperRecord.Variant.Variant '[]) instance (GHC.Classes.Ord t, GHC.Classes.Ord (SuperRecord.Variant.Variant ts)) => GHC.Classes.Ord (SuperRecord.Variant.Variant (t : ts)) module SuperRecord.Variant.Tagged -- | Just a type alias vor Variant type TaggedVariant opts = Variant opts -- | Helper function to construct a tagged variant value given the tag and -- the value. Note that you can use OverloadedLabels for nicer syntax to -- construct the FldProxy. -- --
--   toTaggedVariant #myTag "myValue"
--   
toTaggedVariant :: forall opts lbl a pos. (KnownSymbol lbl, VariantMember (lbl := a) opts, KnownNat pos, VariantPos (lbl := a) opts ~ pos) => FldProxy lbl -> a -> TaggedVariant opts -- | Convert a variant back to a common Haskell type. Returns nothing if -- the variant is not of the right tag and type. fromTaggedVariant :: forall opts lbl a pos. (KnownSymbol lbl, VariantMember (lbl := a) opts, KnownNat pos, VariantPos (lbl := a) opts ~ pos) => FldProxy lbl -> TaggedVariant opts -> Maybe a -- | Nicer syntax for VariantCase for tagged variants. taggedVariantCase :: forall lbl t ts r. FldProxy lbl -> (t -> r) -> VariantMatch r ts -> VariantMatch r ((lbl := t) : ts) -- | Newtype wrapper for TaggedVariant which provides a useful JSON -- encoding of tagged variants in the form {"tag": value} newtype JsonTaggedVariant opts JsonTaggedVariant :: TaggedVariant opts -> JsonTaggedVariant opts [unJsonTaggedVariant] :: JsonTaggedVariant opts -> TaggedVariant opts instance Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant '[]) instance (GHC.TypeLits.KnownSymbol lbl, Data.Aeson.Types.ToJSON.ToJSON t, Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant ts)) => Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant ((lbl SuperRecord.Field.:= t) : ts)) instance Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant '[]) instance (Data.Aeson.Types.FromJSON.FromJSON t, Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant ts), GHC.TypeLits.KnownSymbol lbl) => Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Tagged.JsonTaggedVariant ((lbl SuperRecord.Field.:= t) : ts)) module SuperRecord.Variant.Text -- | A text only variant: A wrapped Text that can only be one of the -- given values tracked at type level. Very useful for interacting with -- enum-like string in JSON APIs. data TextVariant (opts :: [Symbol]) -- | An empty TextVariant, equivalent to `()` emptyTextVariant :: TextVariant '[] -- | Create a TextVariant value from a statically known string. Use -- OverloadedLabels for nice syntax: toTextVariant #myString toTextVariant :: forall opts lbl. (KnownSymbol lbl, TextVariantMember lbl opts) => FldProxy lbl -> TextVariant opts -- | Convert a TextVariant back to a normal Text. This -- operation is cheap since TextVariant is a simple newtype. fromTextVariant :: TextVariant opts -> Text data TextVariantMatch r ts [TextVariantCase] :: FldProxy lbl -> r -> TextVariantMatch r ts -> TextVariantMatch r (lbl : ts) [TextVariantEnd] :: TextVariantMatch r '[] [TextVariantWildCard] :: r -> TextVariantMatch r ts -- | Pattern matching helper with totality check. Note that the performance -- of this pattern match is roughly like a normal pattern match. (See -- benchmarks) class TextVariantMatcher r opts textVariantMatch :: TextVariantMatcher r opts => TextVariant opts -> TextVariantMatch r opts -> r -- | Build a variant from a text that is not statically known at compile -- time. Returns Nothing on failure (i.E. when a value is given -- that is not part of the variant) class TextVariantBuilder opts buildTextVariant :: TextVariantBuilder opts => Text -> Maybe (TextVariant opts) instance Control.DeepSeq.NFData (SuperRecord.Variant.Text.TextVariant opts) instance GHC.Classes.Ord (SuperRecord.Variant.Text.TextVariant opts) instance GHC.Classes.Eq (SuperRecord.Variant.Text.TextVariant opts) instance GHC.Show.Show (SuperRecord.Variant.Text.TextVariant opts) instance SuperRecord.Variant.Text.TextVariantBuilder opts => Data.Aeson.Types.FromJSON.FromJSON (SuperRecord.Variant.Text.TextVariant opts) instance (GHC.TypeLits.KnownSymbol lbl, SuperRecord.Variant.Text.TextVariantBuilder ts) => SuperRecord.Variant.Text.TextVariantBuilder (lbl : ts) instance SuperRecord.Variant.Text.TextVariantBuilder '[] instance (GHC.TypeLits.KnownSymbol lbl, SuperRecord.Variant.Text.TextVariantMatcher r ts) => SuperRecord.Variant.Text.TextVariantMatcher r (lbl : ts) instance SuperRecord.Variant.Text.TextVariantMatcher r '[] instance Data.Aeson.Types.ToJSON.ToJSON (SuperRecord.Variant.Text.TextVariant opts)