-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Entity based records -- -- Typical usage is described at -- http://github.com/nonowarn/has/blob/master/examples/Announce04.lhs. @package has @version 0.5.0.0 -- | Entiry based records. To use this module, you have to write LANGUGAGE -- pragma -- --
-- {-# LANGUAGE TypeFamilies,TypeOperators,FlexibleContexts #-}
--
--
-- Or OPTIONS_GHC pragma if you are lazy.
--
--
-- {-# OPTIONS_GHC -fglasgow-exts #-}
--
module Data.Has
-- | Meaning of this constraint is "This record s has a field of
-- entity e." Here, I use the word "constraint" for class which
-- is useful on writing type signitures.
--
-- Holds v == (e .^ (e ^= v $ s)) where e :: e; v :: TypeOf
-- e; s :: s for all e with TypeOf e and
-- s.
--
-- Same as Knows e (TypeOf e) s.
class Knows e (TypeOf e) r => Has e r
-- | Field a is a type list which contains only one element of
-- a. And every field in the records should be this type.
--
-- If you concatenate fields with (:&:) at type-level,
-- (&) at value-level, it becomes a record can be
-- manipulated by functions in this module.
type Field a = a ::: TyNil
-- | Creates a Field of a.
field :: a -> Field a
-- | Creates a field labelled by a
fieldOf :: TypeOf a -> FieldOf a
-- | Writes field of e in r with TypeOf e.
(^=) :: Knows e (TypeOf e) r => e -> TypeOf e -> r -> r
-- | Reads TypeOf e from field of e in r.
(^.) :: Knows e (TypeOf e) r => e -> r -> TypeOf e
-- | Modifies field of e in r with given function
-- TypeOf e -> | TypeOf e.
(^:) :: Knows e (TypeOf e) r => e -> (TypeOf e -> TypeOf e) -> (r -> r)
-- | Creates field of e with given value TypeOf e.
-- Stealed from Chris Drone's blog post:
-- http://chrisdone.com/posts/2010-11-22-duck-typing-in-haskell.html
(^-) :: e -> TypeOf e -> FieldOf e
-- | Injects and projects a value of v a corresponding field in
-- records a along entity e.
--
-- Holds v == prjl e (injl e v r).
class Contains (Labelled e v) r => Knows e v r | e r -> v
injl :: Knows e v r => e -> v -> r -> r
prjl :: Knows e v r => e -> r -> v
-- | Updates a value of v in a record r using function of
-- v -> v.
updl :: Knows e v r => e -> (v -> v) -> (r -> r)
-- | Represents labelled value.
data Labelled lab a
-- | Represents labelled field.
type :> lab a = Field (Labelled lab a)
-- | Makes a labelled field.
(.>) :: lab -> a -> lab :> a
-- | TypeOf a should indicate a type labelled by a. When
-- defining entities, declare instance of this family. If you want
-- Foo entity points to Int, you write
--
-- -- data Foo = Foo; type instance TypeOf Foo = Int ---- | Field labelled with a, and contains TypeOf a. -- | Concatenates between Fields or records. Records are -- concatenated rows. For example, Following expressions are valid. -- --
-- -- Concatenation of rows (i.e. record) -- field "string" & field True ---- --
-- -- Concatenation of records -- (field 'c' & field ()) & (field False & field "string") ---- --
-- -- ... And concatenations between a field and a record -- field () & (field False & field "string") -- (field 'c' & field ()) & field False --(&) :: Append a b => a -> b -> a :&: b -- | Represents concatenated rows or records. -- | Cons a type onto type-list. data (:::) a b -- | The empty type-list. data TyNil -- | Provides injection and projection into type lists. -- -- Holds e == prj (inj e s) for all s and e. class Contains e s instance Typeable2 Labelled instance Eq a => Eq (Labelled lab a) instance Ord a => Ord (Labelled lab a) instance Show a => Show (Labelled lab a) instance Read a => Read (Labelled lab a) instance Bounded a => Bounded (Labelled lab a) instance (Data lab, Data a) => Data (Labelled lab a) instance CoArbitrary a => CoArbitrary (Labelled lab a) instance Arbitrary a => Arbitrary (Labelled lab a) instance Monoid a => Monoid (Labelled lab a) instance Knows e (TypeOf e) r => Has e r instance Contains (Labelled e v) r => Knows e v r