-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Types and helpers for composing types into a single larger key-value type.
--   
--   A library providing generic types and helpers for composing types
--   together into a a single key-value type.
--   
--   This is useful when a normalized data model has a denormalized
--   serialization format. Using this libraries types and functions you
--   build compose your data into the denormalized key-value format needed
--   for serialization. Other libraries provide concrete implementations
--   for a given serialization format.
@package composable-associations
@version 0.1.0.0

module Data.ComposableAssociation

-- | A type representing a key-value association where the "key" itself
--   exists only at the type level.
--   
--   <pre>
--   &gt;&gt;&gt; let x = Association Proxy [1, 2, 3] :: Asssociation "type-level-key" [Int]
--   </pre>
--   
--   This type exists primarily as a way to "tag" data with a key for the
--   purpose of serializing haskell data into formats that have a key-value
--   representation (ex: a JSON object).
--   
--   The example above represents a serializable key-value pair with a key
--   of <tt>"type-level-key"</tt> and a value of <tt>[1, 2, 3]</tt>.
--   
--   Storing the key as type-level information allows for unambiguous
--   deserialization.
data Association key value
Association :: Proxy key -> value -> Association key value

-- | A type representing the composition of a base type (which can be
--   serialized into a key-value structure) along with a key-value type.
--   
--   This type exists as a way to compose a haskell value that has a
--   key-value representation (ex: a haskell record where its fields are
--   keys to their values) with additional key-value associations into a
--   single key-value object.
--   
--   This is intended for use with <tt>Association</tt> to add additional
--   key-values to a type for the purposes of
--   serialization/deserialization.
--   
--   For example:
--   
--   <pre>
--   &gt;&gt;&gt; data User = User { name :: String, age :: Int }
--   
--   &gt;&gt;&gt; let alice = User "Alice" 26
--   
--   &gt;&gt;&gt; let bob = User "Bob" 25
--   
--   &gt;&gt;&gt; let charlie = User "Charlie" 27
--   
--   &gt;&gt;&gt; let bobsFriends = [alice, charlie]
--   
--   &gt;&gt;&gt; bobAndFriends :: User :&lt;&gt; Association "friends" [User]
--   
--   &gt;&gt;&gt; let bobAndFriends = bob :&lt;&gt; Association Proxy bobsFriends
--   </pre>
--   
--   While <tt>(bob, bobsFriends)</tt> contains the same values as
--   <tt>bobAndFriends</tt>, it lacks information about how to combine
--   <tt>bob</tt> and <tt>bobsFriends</tt> together into a single
--   serialized key-value object (as well as how to deserialize that back
--   into haskell values).
data base :<> assoc
(:<>) :: base -> assoc -> (:<>) base assoc

-- | Type alias for the (:&lt;&gt;) type operator.
--   
--   Useful if you don't like the TypeOperators extension.
type WithAssociation base assoc = base :<> assoc

-- | Function alias for the <tt>(:&lt;&gt;)</tt> type constructor.
withAssociation :: a -> b -> WithAssociation a b

-- | Convenience function for creating associations.
--   
--   This is especially useful when type-inference elsewhere in your
--   program will determine the type of the Association.
--   
--   <pre>
--   &gt;&gt;&gt; let x = asValue True :: Association "whatever-key" Bool
--   </pre>
asValue :: obj -> Association key obj

-- | Convenience function for changing the type of the
--   <tt>Association</tt>'s key.
--   
--   <pre>
--   &gt;&gt;&gt; let x = Association Proxy 10 :: Association "key-x" Int
--   
--   &gt;&gt;&gt; let y = reKey x :: Association "key-y" Int
--   </pre>
reKey :: Association key obj -> Association key' obj

-- | <pre>
--   _value :: Lens value value' (Association key value) (Association key value')
--   </pre>
_value :: Functor f => (value -> f value') -> Association key value -> f (Association key value')

-- | <pre>
--   _assoc :: Lens assoc assoc' (base :&lt;&gt; assoc) (base :&lt;&gt; assoc')
--   </pre>
_assoc :: Functor f => (assoc -> f assoc') -> (base :<> assoc) -> f (base :<> assoc')

-- | <pre>
--   _base :: Lens base base' (base :&lt;&gt; assoc) (base' :&lt;&gt; assoc)
--   </pre>
_base :: Functor f => (base -> f base') -> (base :<> assoc) -> f (base' :<> assoc)

-- | Generic encoding exception for when a <tt>:&lt;&gt;</tt> "base" cannot
--   be encoded as something object-like.
--   
--   Each serialization should have a more specific version of this
--   exception to convey information about the failure.
data ObjectEncodingException
ObjectEncodingException :: e -> ObjectEncodingException
instance Data.Traversable.Traversable ((Data.ComposableAssociation.:<>) base)
instance Data.Foldable.Foldable ((Data.ComposableAssociation.:<>) base)
instance GHC.Base.Functor ((Data.ComposableAssociation.:<>) base)
instance GHC.Generics.Generic (base Data.ComposableAssociation.:<> assoc)
instance (GHC.Classes.Eq base, GHC.Classes.Eq assoc) => GHC.Classes.Eq (base Data.ComposableAssociation.:<> assoc)
instance (GHC.Show.Show base, GHC.Show.Show assoc) => GHC.Show.Show (base Data.ComposableAssociation.:<> assoc)
instance forall k (key :: k). Data.Traversable.Traversable (Data.ComposableAssociation.Association key)
instance forall k (key :: k). Data.Foldable.Foldable (Data.ComposableAssociation.Association key)
instance forall k (key :: k). GHC.Base.Functor (Data.ComposableAssociation.Association key)
instance forall k (key :: k) value. GHC.Generics.Generic (Data.ComposableAssociation.Association key value)
instance forall k (key :: k) value. GHC.Classes.Eq value => GHC.Classes.Eq (Data.ComposableAssociation.Association key value)
instance forall k (key :: k) value. GHC.Show.Show value => GHC.Show.Show (Data.ComposableAssociation.Association key value)
instance GHC.Show.Show Data.ComposableAssociation.ObjectEncodingException
instance GHC.Exception.Type.Exception Data.ComposableAssociation.ObjectEncodingException
