module Data.CompactSequence.Internal.Numbers where import Data.Bits -- A representation of 1-2 binary numbers. We use this to build stacks or stack -- fragments of known size. data Dyadic = DOne !Dyadic | DTwo !Dyadic | DEnd deriving (Eq, Show) toDyadic :: Int -> Dyadic toDyadic n0 = go (n0 + 1) where go 1 = DEnd go n = case n .&. 1 of 0 -> DOne $ go (unsafeShiftR n 1) _ -> DTwo $ go (unsafeShiftR n 1) {-# NOINLINE toDyadic #-} {- -- We'll have to figure out how to write something -- like this to append stacks more efficiently. incDyadic :: Dyadic -> Dyadic incDyadic DEnd = DOne DEnd incDyadic (DOne n) = DTwo n incDyadic (DTwo n) = DOne (incDyadic n) addDyadic :: Dyadic -> Dyadic -> Dyadic addDyadic = go 0 where go 0 DEnd !n = n go 1 DEnd !n = incDyadic n go _ DEnd !n = incDyadic (incDyadic n) go !c !n DEnd = go c DEnd n go !c -} -- A representation of 2-3 binary numbers, where the most significant digit may -- also be 1. We use this to build stacks or stack fragments of known size. data Bin23 = Two23 !Bin23 | Three23 !Bin23 | End23 | OneEnd23 deriving (Eq, Show) toBin23 :: Int -> Bin23 toBin23 n0 = go (n0 + 2) where go 2 = End23 go 3 = OneEnd23 go n = case n .&. 1 of 0 -> Two23 $ go (unsafeShiftR n 1) _ -> Three23 $ go (unsafeShiftR n 1) {-# NOINLINE toBin23 #-} data Bin45 = Four45 !Bin45 | Five45 !Bin45 | End45 | OneEnd45 | TwoEnd45 | ThreeEnd45 toBin45 :: Int -> Bin45 toBin45 n0 = go (n0 + 4) where go 4 = End45 go 5 = OneEnd45 go 6 = TwoEnd45 go 7 = ThreeEnd45 go n = case n .&. 1 of 0 -> Four45 $ go (unsafeShiftR n 1) _ -> Five45 $ go (unsafeShiftR n 1) {-# NOINLINE toBin45 #-}