-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Finite ranges via types
--
-- A framework for capturing finite ranges with types, where the sizes of
-- the ranges are not fixed statically at compile time, but instead are
-- passed at run-time via implicit parameters.
--
-- This is especially useful for objects of bounded size, e.g. finite
-- automata, where the number of elements being part of the object, e.g.
-- the number of states, is well-defined in the context of the object.
@package finite
@version 1.4.1.2
-- | Template haskell for easy instance generation using newtypes.
module Finite.TH
-- | Creates a new basic type using the name provided as a string. The
-- template defines the corresponding data type using the provided name
-- and a corresponding access function using the same name with the first
-- letter moved to lower case. Furthermore, it also instanciates
-- corresponding Show, Hashable, Ix,
-- Arbitrary, and Num instances.
--
--
-- >>> newInstance "Example"
--
-- newtype Example =
-- Example { example :: Int }
-- deriving (Eq, Ord)
--
-- instance Show Example where
-- show (Example x) = show x
--
-- instance Hashable Example where
-- hashWithSalt s (Example x) = hashWithSalt s x
--
-- instance Ix Example where
-- range (l,u) = map Example $ range (example l, example u)
-- index (l,u) x = index (example l, example u) (example x)
-- inRange (l,u) x = inRange (example l, example u) (example x)
--
-- instance Arbitrary Example where
-- arbitrary = Example <$> arbitrary
-- shrink (Example x) = map Example $ shrink x
--
-- instance Num Example where
-- (Example x) + (Example y) = Example (a + b)
-- (Example x) - (Example y) = Example (a - b)
-- (Example x) * (Example y) = Example (a * b)
-- abs = Example . abs . example
-- negate = Example . negage . example
-- signum = Example . signum . example
-- fromInteger = Example . fromInteger
--
newInstance :: String -> Q [Dec]
-- | Creates a basic finite instance using the bounds provided via the
-- first argument, the access function provided by the second argument
-- and the name provided as a string.
--
--
-- >>> baseInstance [t|Bounds|] [|getBound|] "Example"
--
-- instance Finite Bounds Example where
-- elements _ = getBound ?bounds
-- value = Example
-- index = example
--
baseInstance :: Q Type -> Q Exp -> String -> Q [Dec]
-- | Combined newInstance with baseInstance.
newBaseInstance :: Q Type -> Q Exp -> String -> Q [Dec]
-- | Extends a Finite instance to an extended parameter space. The first
-- argument takes the type to be extended, the second argument the type
-- of the new parameter space and the third argument a translator
-- function that translates the old parameter space into the new one.
--
--
-- >>> :i Bounds
--
-- instance Finite Bounds Example
--
--
-- >>> :t derive
--
-- derive :: NewBounds -> Bounds
--
--
-- >>> extendInstance [t|Example|] [t|NewBounds] [|translate|]
--
-- instance Finite NewBounds Example where
-- elements = let ?bounds = translate ?bounds in elements
-- offset = let ?bounds = translate ?bounds in offset
-- value = let ?bounds = translate ?bounds in value
-- index = let ?bounds = translate ?bounds in index
--
extendInstance :: Q Type -> Q Type -> Q Exp -> Q [Dec]
-- | Constructs a polymorph type given a type constructor and a free type
-- variable. Such a construction cannot be expressed in quotation syntax
-- directly.
--
--
-- >>> polyType [t|Maybe|] "a"
--
-- Maybe a
--
polyType :: Q Type -> String -> Q Type
-- | A framework for capturing finite ranges with types, where the sizes of
-- the ranges are not fixed statically at compile time, but instead are
-- passed at run-time via implicit parameters. The purpose of the
-- framework is to simplify the handling of objects of bounded size, e.g.
-- finite-state machines, where the number of elements can be defined in
-- the context of the object, e.g. the number of states.
--
-- The framework supports:
--
--
-- - Easy access to the object's elements via types.
-- - Efficient bidirectional mappings between indices and the
-- elements.
-- - Implicit total orderings on the elements.
-- - Powerset Support.
-- - Extension of a single context to a range of contexts via
-- collections.
-- - Easy passing of the context via implict parameters.
-- - Generics Support: Finite range types can be easily constructed out
-- of other finite range types using Haskell's `data` constructor.
-- - Template Haskell: Easy creation of basic finite instances using
-- short Haskell templates, as well as the extension of existing types to
-- more feature rich parameter spaces (requires the explicit import of
-- Finite.TH).
--
module Finite
-- | The Finite class.
class Finite b a
-- | Returns the number of elements associated with the given type.
elements :: (Finite b a, FiniteBounds b) => T a -> Int
-- | Returns the number of elements associated with the given type.
elements :: (Finite b a, Generic a, GFinite b (Rep a), FiniteBounds b) => T a -> Int
-- | Turns the value in the associated range into an Int uniquely
-- identifiying the value.
index :: (Finite b a, FiniteBounds b) => a -> Int
-- | Turns the value in the associated range into an Int uniquely
-- identifiying the value.
index :: (Finite b a, Generic a, GFinite b (Rep a), FiniteBounds b) => a -> Int
-- | Turns an Int back to the value that is associated with it.
value :: (Finite b a, FiniteBounds b) => Int -> a
-- | Turns an Int back to the value that is associated with it.
value :: (Finite b a, Generic a, GFinite b (Rep a), FiniteBounds b) => Int -> a
-- | Allows to put an offset to the integer mapping. Per default the offset
-- is zero.
offset :: (Finite b a, FiniteBounds b) => T a -> Int
-- | Returns a finite list of all elements of that type.
values :: (Finite b a, FiniteBounds b) => [a]
-- | Complements a given list of elements of that type
complement :: (Finite b a, FiniteBounds b) => [a] -> [a]
-- | Less than operator according to the implicit total index order.
(|<|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | Less or equal than operator according to the implicit total index
-- order.
(|<=|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | Greater or equal than operator according to the implicit total index
-- order.
(|>=|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | Greater than operator according to the implicit total index order.
(|>|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | Equal operator according to the implicit total index order.
(|==|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | Unequal operator according to the implicit total index order.
(|/=|) :: (Finite b a, FiniteBounds b) => a -> a -> Bool
-- | First element according to the total index order.
initial :: (Finite b a, FiniteBounds b) => T a -> a
-- | Last element according to the total index order.
final :: (Finite b a, FiniteBounds b) => T a -> a
-- | Next element according to the total index order (undefined for the
-- last element).
next :: (Finite b a, FiniteBounds b) => a -> a
-- | Previous element according to the total index order (undefined for the
-- first element).
previous :: (Finite b a, FiniteBounds b) => a -> a
-- | The upper and lower bounds of the instance.
bounds :: (Finite b a, FiniteBounds b) => T a -> (a, a)
infixr 9 |<|
infixr 9 |<=|
infixr 9 |>=|
infixr 9 |>|
infixr 9 |==|
infixr 9 |/=|
-- | Generics implementation for the Finite class. The realization
-- is closely related to the one presented at
-- https://wiki.haskell.org/GHC.Generics.
class GFinite b f
gelements :: (GFinite b f, FiniteBounds b) => T (f a) -> Int
gindex :: (GFinite b f, FiniteBounds b) => f a -> Int
gvalue :: (GFinite b f, FiniteBounds b) => Int -> f a
-- | A better looking constraint specifier.
type FiniteBounds b = (?bounds :: b)
-- | Powersets are just lists of the correpsonding elements. The type has
-- only been added for clearification. Consider the corresponding
-- instance of Finite for possible applications.
type PowerSet a = [a]
-- | The Collection type provides a set of items, each assigning an
-- index of type i to a value of type a.
data Collection i a
Item :: i -> a -> Collection i a
-- | A type dummy.
data T a
-- | The type dummy instance.
(#) :: T a
-- | A type dummy returning function. Intended to use the type engine for
-- accessing the type of the argument. Note that "(\#) :: a -> T
-- a" is just a special instance.
(\#) :: b -> T a
-- | Replace a function's argument by its type dummy. Intended to be used
-- for extracting type information of polymorph types only.
(<<#) :: (a -> b) -> T a -> b
infixr 9 <<#
-- | Replace a function's dummy type argument with its value taking
-- equivalent.
(#<<) :: (T a -> b) -> a -> b
infixr 9 #<<
-- | Get the type of a given value.
v2t :: a -> T a
-- | Get some undefined value of the given type. Intended to be used for
-- extracting type information of polymorph types only.
t2v :: T a -> a