finitary-derive-2.0.0.0: Flexible and easy deriving of type classes for finitary types.
Copyright(C) Koz Ross 2019
LicenseGPL version 3.0 or later
Maintainerkoz.ross@retro-freedom.nz
StabilityExperimental
PortabilityGHC only
Safe HaskellTrustworthy
LanguageHaskell2010

Data.Finitary.Finiteness

Description

Knowing that a type a is an instance of Finitary gives us the knowledge that there is an isomorphism between a and Finite n for some KnownNat n. This gives us a lot of information, which we can exploit to automagically derive a range of type class instances.

Finiteness is a newtype wrapper providing this functionality, while 're-exporting' as many type class instances of the underlying type as possible. It is designed for use with DerivingVia - an example of use:

{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics
import Data.Finitary
import Data.Finitary.Finiteness
import Data.Word
import Control.DeepSeq
import Data.Hashable
import Data.Binary

data Foo = Bar | Baz (Word8, Word8) | Quux Word16
 deriving (Eq, Generic, Finitary)
 deriving (Ord, Bounded, NFData, Hashable, Binary) via (Finiteness Foo)

Currently, the following type class instances can be derived in this manner:

Additionally, Finiteness 'forwards' definitions of the following type classes:

Synopsis

Documentation

newtype Finiteness a Source #

Essentially Identity with a different name. Named this way due to the wordplay you get from use with DerivingVia.

Constructors

Finiteness 

Fields

Instances

Instances details
Functor Finiteness Source # 
Instance details

Defined in Data.Finitary.Finiteness

Methods

fmap :: (a -> b) -> Finiteness a -> Finiteness b #

(<$) :: a -> Finiteness b -> Finiteness a #

(Finitary a, 1 <= Cardinality a) => Bounded (Finiteness a) Source #

Since any inhabited Finitary type is also Bounded, we can forward this definition also.

Instance details

Defined in Data.Finitary.Finiteness

Eq a => Eq (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Methods

(==) :: Finiteness a -> Finiteness a -> Bool #

(/=) :: Finiteness a -> Finiteness a -> Bool #

Data a => Data (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Finiteness a -> c (Finiteness a) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Finiteness a) #

toConstr :: Finiteness a -> Constr #

dataTypeOf :: Finiteness a -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Finiteness a)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Finiteness a)) #

gmapT :: (forall b. Data b => b -> b) -> Finiteness a -> Finiteness a #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Finiteness a -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Finiteness a -> r #

gmapQ :: (forall d. Data d => d -> u) -> Finiteness a -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Finiteness a -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Finiteness a -> m (Finiteness a) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Finiteness a -> m (Finiteness a) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Finiteness a -> m (Finiteness a) #

Finitary a => Ord (Finiteness a) Source #

Ord can be derived by deferring to the order on Finite (Cardinality a).

Instance details

Defined in Data.Finitary.Finiteness

Read a => Read (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Show a => Show (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Semigroup a => Semigroup (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Monoid a => Monoid (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

Finitary a => Binary (Finiteness a) Source #

Any Finitary type can be converted to a binary representation by converting its index.

Instance details

Defined in Data.Finitary.Finiteness

Methods

put :: Finiteness a -> Put #

get :: Get (Finiteness a) #

putList :: [Finiteness a] -> Put #

Finitary a => NFData (Finiteness a) Source #

We can force evaluation of a Finitary type by converting it to its index.

Instance details

Defined in Data.Finitary.Finiteness

Methods

rnf :: Finiteness a -> () #

Finitary a => Finitary (Finiteness a) Source #

Finiteness merely replicates the Finitary behaviour of the underlying type.

Instance details

Defined in Data.Finitary.Finiteness

Associated Types

type Cardinality (Finiteness a) :: Nat

Methods

fromFinite :: Finite (Cardinality (Finiteness a)) -> Finiteness a

toFinite :: Finiteness a -> Finite (Cardinality (Finiteness a))

start :: Finiteness a

end :: Finiteness a

previous :: Alternative f => Finiteness a -> f (Finiteness a)

next :: Alternative f => Finiteness a -> f (Finiteness a)

Finitary a => Hashable (Finiteness a) Source #

Any Finitary type can be hashed by hashing its index.

Instance details

Defined in Data.Finitary.Finiteness

Methods

hashWithSalt :: Int -> Finiteness a -> Int

hash :: Finiteness a -> Int

type Cardinality (Finiteness a) Source # 
Instance details

Defined in Data.Finitary.Finiteness

type Cardinality (Finiteness a) = Cardinality a