random-fu-0.0.0.2: src/Data/Random/Internal/Classification.hs
{-# LANGUAGE
MultiParamTypeClasses, FunctionalDependencies,
EmptyDataDecls
#-}
{-
- ``Data/Random/Internal/Classification''
-}
-- | \"Classification systems\" - for a motivating example, see
-- the implementation of the Uniform distribution. Basically,
-- I would like to make instances like:
--
-- > instance RealFloat a => Distribution Uniform a where ...
-- > instance Integral a => Distribution Uniform a where ...
--
-- and so on. However, this is not sound - what happens if someone
-- comes along and makes a type that's an instance of both Integral and
-- RealFloat?
--
-- So, we introduce a classification system based on phantom types, so
-- that each type can be unambiguously declared to be \"intensionally\"
-- Integral, Floating, or whatever.
--
-- Now, obviously it'd be nice not to clutter the Distribution typeclass
-- with extra phantom types that the end user shouldn't care about. Hence
-- the pattern of introducing typeclasses such as "UniformByClassification"
--
-- Now, if a new type comes along that is Integral, a single declaration
-- of the following form suffices to attach it to all such Distribution
-- instances:
--
-- > instance Classification NumericType t IntegralType
--
-- Not quite as automagic as the @Integral a => Distribution foo@ case,
-- but a bit closer. Not only that, it leaves open the possibility that
-- a user may bring in a type that is \"mostly\" integral, and has an Integral
-- instance, but should be handled differently for purposes of uniform
-- random number generation. In such a case, the user may introduce a new
-- classification of their own and provide the required instances for that
-- classification.
--
-- All in all, although it is not yet well-tested, it has the \"feel\" of
-- a good compromise.
module Data.Random.Internal.Classification where
import Data.Int
import Data.Word
import Data.Ratio
-- |classificiation system, experimental
--
-- * c (a phantom type) is the classification system
--
-- * t is the type to be classified
--
-- * tc (a phantom type) is the classification of t according to c
--
-- The functional dependency, aside from being important because the relation
-- is functional, allows the classification system to be \"discharged\" in
-- cases such as the following:
--
-- > class Classification SomeCS t c => FooByClassification t c where ...
-- > instance FooByClassification t c => Foo t where ...
--
-- Thus the class of interest to the end user need not display anything
-- at all about the classification system, except in the superclasses of
-- the classes in the contexts of some of its instances.
class Classification c t tc | c t -> tc
-- |A simple classification system covering the cases we care
-- about when sampling distributions. Loosely, these are the reasons we care:
--
-- * distributions over Fractional types are handled as if the type were continuous.
--
-- * distributions over Integral types are handled discretely.
--
-- * distributions over Enum types (which are not Num instances) are handled
-- like Integral types, but require use of 'fromEnum' and/or 'toEnum' to work with them.
data NumericType
data IntegralType
data FractionalType
data EnumType
instance Classification NumericType Int IntegralType
instance Classification NumericType Int8 IntegralType
instance Classification NumericType Int16 IntegralType
instance Classification NumericType Int32 IntegralType
instance Classification NumericType Int64 IntegralType
instance Classification NumericType Word8 IntegralType
instance Classification NumericType Word16 IntegralType
instance Classification NumericType Word32 IntegralType
instance Classification NumericType Word64 IntegralType
instance Classification NumericType Integer IntegralType
instance Classification NumericType Float FractionalType
instance Classification NumericType Double FractionalType
instance Classification NumericType (Ratio a) FractionalType
instance Classification NumericType Char EnumType
instance Classification NumericType Bool EnumType
instance Classification NumericType () EnumType
instance Classification NumericType Ordering EnumType