Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This library provide a brief implementation for extensible records. It is sensitive to the ordering of key-value items, but has simple type constraints and provides short compile time.
Synopsis
- data KVList (kvs :: [Type])
- data (key :: Symbol) := (value :: Type) where
- (&=) :: (KnownSymbol k, Appended kvs '[k := v] ~ appended) => KVList kvs -> (k := v) -> KVList appended
- (&=>) :: (Applicative f, KnownSymbol k, Appended kvs '[k := v] ~ appended) => f (KVList kvs) -> (k := f v) -> f (KVList appended)
- kvcons :: KnownSymbol k => (k := v) -> KVList kvs -> KVList ((k := v) ': kvs)
- empty :: KVList '[]
- singleton :: KnownSymbol k => (k := v) -> KVList '[k := v]
- data ListKey (t :: Symbol) = ListKey
- get :: (KnownSymbol key, HasKey key kvs v) => ListKey key -> KVList kvs -> v
- type HasKey (key :: Symbol) (kvs :: [Type]) (v :: Type) = HasKey_ key kvs kvs v
- (&.) :: (KnownSymbol key, HasKey key kvs v) => KVList kvs -> ListKey key -> v
- (&.?) :: (KnownSymbol key, HasKey key kvs v, Functor f) => f (KVList kvs) -> ListKey key -> f v
- (&.??) :: (KnownSymbol key, HasKey key kvs (m v), Monad m) => m (KVList kvs) -> ListKey key -> m v
Constructors
We can create type level KV list as follows.
>>>
:set -XOverloadedLabels -XTypeOperators
>>>
import Prelude
>>>
import Data.KVList (empty, KVList, (:=)((:=)), (&.), (&=))
>>>
import qualified Data.KVList as KVList
>>>
let sampleList = KVList.empty &= #foo := "str" &= #bar := 34
>>>
type SampleList = KVList '[ "foo" := String, "bar" := Int ]
data KVList (kvs :: [Type]) Source #
A value with type level key.
data (key :: Symbol) := (value :: Type) where infix 2 Source #
(&=) :: (KnownSymbol k, Appended kvs '[k := v] ~ appended) => KVList kvs -> (k := v) -> KVList appended infixl 1 Source #
(&=>) :: (Applicative f, KnownSymbol k, Appended kvs '[k := v] ~ appended) => f (KVList kvs) -> (k := f v) -> f (KVList appended) infixl 1 Source #
Applicative version of (&=)
.
>>>
import Data.KVList ((&=>))
>>>
:{
pure KVList.empty &=> #foo := (Just 3) &=> #bar := (Just "bar") :} Just (KVList.empty &= #foo := 3 &= #bar := "bar")
>>>
:{
pure KVList.empty &=> #foo := (Just 3) &=> #bar := Nothing :} Nothing
data ListKey (t :: Symbol) Source #
ListKey
is just a proxy, but needed to implement a non-orphan IsLabel
instance.
In most cases, you only need to create a ListKey
instance with OverloadedLabels
, such as `#foo`.
Operators
(&.?) :: (KnownSymbol key, HasKey key kvs v, Functor f) => f (KVList kvs) -> ListKey key -> f v infixl 9 Source #
Helper operator for optional chain.
(&.?) mkvs k = fmap (&. k) mkvs
>>>
import Data.KVList ((&.?))
>>>
:{
( KVList.empty &= #foo := Just (KVList.empty &= #bar := "bar" ) ) &. #foo &.? #bar :} Just "bar"
(&.??) :: (KnownSymbol key, HasKey key kvs (m v), Monad m) => m (KVList kvs) -> ListKey key -> m v infixl 9 Source #
Helper operator for optional chain.
(&.??) mkvs k = (&. k) =<< mkvs
>>>
import Data.KVList ((&.??))
>>>
:{
( KVList.empty &= #foo := Just (KVList.empty &= #bar := Just "bar" ) ) &. #foo &.?? #bar :} Just "bar"