-- 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


-- | <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 {
    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 -> *
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
