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


-- | A library for generic programming that aims to be easy to understand
--   
--   Documentation is here: <a>https://generics-eot.readthedocs.io/</a>
@package generics-eot
@version 0.4.0.1


-- | <tt>generics-eot</tt> tries to be a library for datatype generic
--   programming that is easy to understand. "eot" stands for "eithers of
--   tuples".
--   
--   A tutorial on how to use <tt>generics-eot</tt> can be found here:
--   <a>https://generics-eot.readthedocs.io/</a>.
module Generics.Eot

-- | An instance (<tt><a>HasEot</a> a</tt>) allows us to
--   
--   <ul>
--   <li>convert values of an arbitrary algebraic datatype <tt>a</tt> to
--   and from a generic representation (<tt><a>Eot</a> a</tt>) (see
--   <a>toEot</a> and <a>fromEot</a>).</li>
--   <li>extract meta information about the type <tt>a</tt> (see
--   <a>datatype</a>).</li>
--   </ul>
--   
--   Once an algebraic datatype has an instance for <a>Generic</a> it
--   automatically gets one for <a>HasEot</a>.
class HasEot a where {
    
    -- | <a>Eot</a> is a type level function that maps arbitrary ADTs to
    --   isomorphic generic representations. Here's an example:
    --   
    --   <pre>
    --   data Foo = A Int Bool | B String
    --   </pre>
    --   
    --   would be mapped to:
    --   
    --   <pre>
    --   Either (Int, (Bool, ())) (Either (String, ()) Void)
    --   </pre>
    --   
    --   These representations follow these rules:
    --   
    --   <ul>
    --   <li>The choice between constructors is mapped to right-nested
    --   <a>Either</a>s.</li>
    --   <li>There's always a so-called end-marker <a>Void</a>. It's an invalid
    --   choice (and <a>Void</a> is uninhabited to make sure you don't
    --   accidentally create such a value). So e.g. <tt>data Foo = A</tt> would
    --   be mapped to <tt>Either () Void</tt>, and a type with no constructors
    --   is mapped to <tt>Void</tt>.</li>
    --   <li>The fields of one constructor are mapped to right-nested
    --   tuples.</li>
    --   <li>Again there's always an end-marker, this time of type <tt>()</tt>.
    --   A constructor with three fields <tt>a</tt>, <tt>b</tt>, <tt>c</tt> is
    --   mapped to <tt>(a, (b, (c, ())))</tt>, one field <tt>a</tt> is mapped
    --   to <tt>(a, ())</tt>, and no fields are mapped to <tt>()</tt> (just the
    --   end-marker).</li>
    --   </ul>
    --   
    --   These rules (and the end-markers) are necessary to make sure generic
    --   functions know exactly which parts of the generic representation are
    --   field types and which parts belong to the generic skeleton.
    type family Eot a :: *;
}

-- | Convert a value of type <tt>a</tt> to its generic representation.
toEot :: HasEot a => a -> Eot a

-- | Convert a value in a generic representation to <tt>a</tt> (inverse of
--   <a>toEot</a>).
fromEot :: HasEot a => Eot a -> a

-- | Extract meta information about the ADT.
datatype :: HasEot a => Proxy a -> Datatype

-- | Type for meta information about ADTs.
data Datatype
Datatype :: String -> [Constructor] -> Datatype

-- | unqualified name of the type
[datatypeName] :: Datatype -> String
[constructors] :: Datatype -> [Constructor]
data Constructor
Constructor :: String -> Fields -> Constructor
[constructorName] :: Constructor -> String
[fields] :: Constructor -> Fields

-- | Type that represents meta information about fields of one constructor.
data Fields

-- | Record constructor, containing the list of the selector names.
Selectors :: [String] -> Fields

-- | Constructor with fields, but without selector names. The argument
--   gives the number of fields.
NoSelectors :: Int -> Fields

-- | Constructor without fields.
NoFields :: Fields

-- | Representable types of kind <tt>*</tt>. This class is derivable in GHC
--   with the <tt>DeriveGeneric</tt> flag on.
--   
--   A <a>Generic</a> instance must satisfy the following laws:
--   
--   <pre>
--   <a>from</a> . <a>to</a> ≡ <tt>id</tt>
--   <a>to</a> . <a>from</a> ≡ <tt>id</tt>
--   </pre>
class Generic a

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt>'undefined :: a'</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k) :: forall k. () => k -> Type
Proxy :: Proxy

-- | Uninhabited data type
data Void

-- | Since <a>Void</a> values logically don't exist, this witnesses the
--   logical reasoning tool of "ex falso quodlibet".
--   
--   <pre>
--   &gt;&gt;&gt; let x :: Either Void Int; x = Right 5
--   
--   &gt;&gt;&gt; :{
--   case x of
--       Right r -&gt; r
--       Left l  -&gt; absurd l
--   :}
--   5
--   </pre>
absurd :: () => Void -> a
instance (GHC.Generics.Generic a, Generics.Eot.ImpliedByGeneric a c f) => Generics.Eot.HasEot a
