module Data.Bits( Bits(..), FiniteBits(..), bitDefault, testBitDefault, popCountDefault, toIntegralSized, oneBits, (.^.), (.>>.), (.<<.), (!>>.), (!<<.), And(..), Ior(..), Xor(..), Iff(..), ) where import qualified Prelude() -- do not import Prelude import MiniPrelude import Data.Bits.Base import Data.Bounded import Data.List as List import Mhs.Builtin oneBits :: (FiniteBits a) => a oneBits = complement zeroBits infixl 6 .^. (.^.) :: (Bits a) => a -> a -> a (.^.) = xor infixl 8 .>>. (.>>.) :: (Bits a) => a -> Int -> a (.>>.) = shiftR infixl 8 .<<. (.<<.) :: (Bits a) => a -> Int -> a (.<<.) = shiftL infixl 8 !>>. (!>>.) :: (Bits a) => a -> Int -> a (!>>.) = unsafeShiftR infixl 8 !<<. (!<<.) :: (Bits a) => a -> Int -> a (!<<.) = unsafeShiftL -------- newtype And a = And { getAnd :: a } deriving newtype ( Bounded, -- ^ @since base-4.16 Enum, -- ^ @since base-4.16 Bits, -- ^ @since base-4.16 FiniteBits, -- ^ @since base-4.16 Eq -- ^ @since base-4.16 ) deriving stock ( Show, -- ^ @since base-4.16 Read -- ^ @since base-4.16 ) -- | @since base-4.16 instance (Bits a) => Semigroup (And a) where And x <> And y = And (x .&. y) -- | This constraint is arguably too strong. However, -- as some types (such as 'Natural') have undefined 'complement', this is the -- only safe choice. -- -- @since base-4.16 instance (FiniteBits a) => Monoid (And a) where mempty = And oneBits -- By default, we would get a lazy right fold. This forces the use of a strict -- left fold instead. mconcat = List.foldl' (<>) mempty {-# INLINE mconcat #-} -- | Monoid under bitwise inclusive OR. -- -- >>> getIor (Ior 0xab <> Ior 0x12) :: Word8 -- 187 -- -- @since base-4.16 newtype Ior a = Ior { getIor :: a } deriving newtype ( Bounded, -- ^ @since base-4.16 Enum, -- ^ @since base-4.16 Bits, -- ^ @since base-4.16 FiniteBits, -- ^ @since base-4.16 Eq -- ^ @since base-4.16 ) deriving stock ( Show, -- ^ @since base-4.16 Read -- ^ @since base-4.16 ) -- | @since base-4.16 instance (Bits a) => Semigroup (Ior a) where Ior x <> Ior y = Ior (x .|. y) -- | @since base-4.16 instance (Bits a) => Monoid (Ior a) where mempty = Ior zeroBits -- By default, we would get a lazy right fold. This forces the use of a strict -- left fold instead. mconcat = List.foldl' (<>) mempty {-# INLINE mconcat #-} -- | Monoid under bitwise XOR. -- -- >>> getXor (Xor 0xab <> Xor 0x12) :: Word8 -- 185 -- -- @since base-4.16 newtype Xor a = Xor { getXor :: a } deriving newtype ( Bounded, -- ^ @since base-4.16 Enum, -- ^ @since base-4.16 Bits, -- ^ @since base-4.16 FiniteBits, -- ^ @since base-4.16 Eq -- ^ @since base-4.16 ) deriving stock ( Show, -- ^ @since base-4.16 Read -- ^ @since base-4.16 ) -- | @since base-4.16 instance (Bits a) => Semigroup (Xor a) where Xor x <> Xor y = Xor (x `xor` y) -- | @since base-4.16 instance (Bits a) => Monoid (Xor a) where mempty = Xor zeroBits -- By default, we would get a lazy right fold. This forces the use of a strict -- left fold instead. mconcat = List.foldl' (<>) mempty {-# INLINE mconcat #-} -- | Monoid under bitwise \'equality\'; defined as @1@ if the corresponding -- bits match, and @0@ otherwise. -- -- >>> getIff (Iff 0xab <> Iff 0x12) :: Word8 -- 70 -- -- @since base-4.16 newtype Iff a = Iff { getIff :: a } deriving newtype ( Bounded, -- ^ @since base-4.16 Enum, -- ^ @since base-4.16 Bits, -- ^ @since base-4.16 FiniteBits, -- ^ @since base-4.16 Eq -- ^ @since base-4.16 ) deriving stock ( Show, -- ^ @since base-4.16 Read -- ^ @since base-4.16 ) -- | This constraint is arguably -- too strong. However, as some types (such as 'Natural') have undefined -- 'complement', this is the only safe choice. -- -- @since base-4.16 instance (FiniteBits a) => Semigroup (Iff a) where Iff x <> Iff y = Iff . complement $ (x `xor` y) -- | This constraint is arguably -- too strong. However, as some types (such as 'Natural') have undefined -- 'complement', this is the only safe choice. -- -- @since base-4.16 instance (FiniteBits a) => Monoid (Iff a) where mempty = Iff oneBits -- By default, we would get a lazy right fold. This forces the use of a strict -- left fold instead. mconcat = List.foldl' (<>) mempty {-# INLINE mconcat #-}