Skip to content

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Bodigrim committed Jun 29, 2020
1 parent 580aa81 commit 67ecbbf
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 57 deletions.
57 changes: 20 additions & 37 deletions src/System/Random/GFinite.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@
-- Maintainer : libraries@haskell.org
--

{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

module System.Random.GFinite
( Cardinality(..)
Expand All @@ -29,26 +22,12 @@ import Data.Bits
import Data.Int
import Data.Void
import Data.Word
import GHC.Generics

#if __GLASGOW_HASKELL__ >= 802

import GHC.Exts (Proxy#, proxy#)
import GHC.Generics

#else

import Data.Proxy

type Proxy# = Proxy

proxy# :: Proxy t
proxy# = Proxy

#endif

-- | Shift n is equivalent to Card (2^n).
-- | Cardinality of a set.
data Cardinality
= Shift !Int
= Shift !Int -- ^ Shift n is equivalent to Card (bit n)
| Card !Integer
deriving (Eq, Ord, Show)

Expand All @@ -57,7 +36,7 @@ instance Enum Cardinality where
fromEnum = fromIntegral

instance Num Cardinality where
fromInteger 1 = Shift 0 -- Unit
fromInteger 1 = Shift 0 -- ()
fromInteger 2 = Shift 1 -- Bool
fromInteger n = Card n
{-# INLINE fromInteger #-}
Expand All @@ -66,12 +45,12 @@ instance Num Cardinality where
{-# INLINE (+) #-}

Shift x * Shift y = Shift (x + y)
Shift x * Card y = Card (y `shiftL` x)
Card x * Shift y = Card (x `shiftL` y)
Card x * Card y = Card (x * y)
Shift x * Card y = Card (y `shiftL` x)
Card x * Shift y = Card (x `shiftL` y)
Card x * Card y = Card (x * y)
{-# INLINE (*) #-}

abs = Card . abs . toInteger
abs = Card . abs . toInteger
signum = Card . signum . toInteger
negate = Card . negate . toInteger

Expand All @@ -81,12 +60,14 @@ instance Real Cardinality where
instance Integral Cardinality where
toInteger = \case
Shift n -> bit n
Card n -> n
Card n -> n
{-# INLINE toInteger #-}

quotRem (toInteger -> x) = \case
quotRem x' = \case
Shift n -> (Card (x `shiftR` n), Card (x .&. (bit n - 1)))
Card n -> let (q, r) = x `quotRem` n in (Card q, Card r)
Card n -> let (q, r) = x `quotRem` n in (Card q, Card r)
where
x = toInteger x'
{-# INLINE quotRem #-}

-- | A type class for data with a finite number of inhabitants.
Expand All @@ -108,7 +89,7 @@ class Finite a where
fromFinite :: a -> Integer

default cardinality :: (Generic a, GFinite (Rep a)) => Proxy# a -> Cardinality
cardinality (_ :: Proxy# a) = gcardinality (proxy# :: Proxy# (Rep a))
cardinality _ = gcardinality (proxy# :: Proxy# (Rep a))

default toFinite :: (Generic a, GFinite (Rep a)) => Integer -> a
toFinite = to . toGFinite
Expand Down Expand Up @@ -154,7 +135,8 @@ instance GFinite a => GFinite (M1 _x _y a) where
{-# INLINE fromGFinite #-}

instance (GFinite a, GFinite b) => GFinite (a :+: b) where
gcardinality _ = gcardinality (proxy# :: Proxy# a) + gcardinality (proxy# :: Proxy# b)
gcardinality _ =
gcardinality (proxy# :: Proxy# a) + gcardinality (proxy# :: Proxy# b)
{-# INLINE gcardinality #-}

toGFinite n
Expand All @@ -180,7 +162,8 @@ instance (GFinite a, GFinite b) => GFinite (a :*: b) where
(q, r) = Card n `quotRem` cardB
{-# INLINE toGFinite #-}

fromGFinite (q :*: r) = toInteger (gcardinality (proxy# :: Proxy# a) * Card (fromGFinite q)) + fromGFinite r
fromGFinite (q :*: r) =
toInteger (gcardinality (proxy# :: Proxy# a) * Card (fromGFinite q)) + fromGFinite r
{-# INLINE fromGFinite #-}

instance Finite Void
Expand All @@ -201,12 +184,12 @@ cardinalityDef _ = Shift (finiteBitSize (0 :: a))

toFiniteDef :: forall a. (Num a, FiniteBits a) => Integer -> a
toFiniteDef n
| isSigned (0 :: a) = fromInteger (n - 1 `shiftL` (finiteBitSize (0 :: a) - 1))
| isSigned (0 :: a) = fromInteger (n - bit (finiteBitSize (0 :: a) - 1))
| otherwise = fromInteger n

fromFiniteDef :: (Integral a, FiniteBits a) => a -> Integer
fromFiniteDef x
| isSigned x = toInteger x + 1 `shiftL` (finiteBitSize x - 1)
| isSigned x = toInteger x + bit (finiteBitSize x - 1)
| otherwise = toInteger x

instance Finite Word8 where
Expand Down
24 changes: 4 additions & 20 deletions src/System/Random/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
Expand Down Expand Up @@ -81,7 +80,7 @@ import Data.Word
import Foreign.C.Types
import Foreign.Ptr (plusPtr)
import Foreign.Storable (Storable(pokeByteOff))
import GHC.Exts hiding (Proxy#, proxy#)
import GHC.Exts
import GHC.Generics
import GHC.IO (IO(..))
import GHC.Word
Expand All @@ -100,21 +99,6 @@ import GHC.ForeignPtr
import Data.ByteString (ByteString)
#endif

#if __GLASGOW_HASKELL__ >= 802

import GHC.Exts (Proxy#, proxy#)

#else

import Data.Proxy

type Proxy# = Proxy

proxy# :: Proxy t
proxy# = Proxy

#endif

-- | 'RandomGen' is an interface to pure pseudo-random number generators.
--
-- 'StdGen' is the standard 'RandomGen' instance provided by this library.
Expand Down Expand Up @@ -556,10 +540,10 @@ instance (GFinite f, GFinite g) => GUniform (f :+: g) where
finiteUniformM :: forall g m f a. (StatefulGen g m, GFinite f) => g -> m (f a)
finiteUniformM = fmap toGFinite . case gcardinality (proxy# :: Proxy# f) of
Shift n
| n <= 64 -> fmap toInteger . unsignedBitmaskWithRejectionM uniformWord64 (1 `shiftL` n - 1)
| n <= 64 -> fmap toInteger . unsignedBitmaskWithRejectionM uniformWord64 (bit n - 1)
| otherwise -> boundedByPowerOf2ExclusiveIntegralM n
Card n
| n <= 1 `shiftL` 64 -> fmap toInteger . unsignedBitmaskWithRejectionM uniformWord64 (fromInteger n - 1)
| n <= bit 64 -> fmap toInteger . unsignedBitmaskWithRejectionM uniformWord64 (fromInteger n - 1)
| otherwise -> boundedExclusiveIntegralM n

-- | The class of types for which a uniformly distributed value can be drawn
Expand Down Expand Up @@ -990,7 +974,7 @@ boundedExclusiveIntegralM s gen = go
{-# INLINE boundedExclusiveIntegralM #-}

-- | boundedByPowerOf2ExclusiveIntegralM s ~ boundedExclusiveIntegralM (bit s)
boundedByPowerOf2ExclusiveIntegralM :: forall a g m . (Bits a, Integral a, StatefulGen g m) => Int -> g -> m a
boundedByPowerOf2ExclusiveIntegralM :: (Bits a, Integral a, StatefulGen g m) => Int -> g -> m a
boundedByPowerOf2ExclusiveIntegralM s gen = do
let n = (s + wordSizeInBits - 1) `quot` wordSizeInBits
x <- uniformIntegralWords n gen
Expand Down

0 comments on commit 67ecbbf

Please sign in to comment.