-- | Bits functions.
module Music.Theory.Bits where

import Data.Bits {- base -}

-- | 'True' = 1, 'False' = 0
bit_pp :: Bool -> Char
bit_pp :: Bool -> Char
bit_pp Bool
b = if Bool
b then Char
'1' else Char
'0'

-- | 'map' 'bit_pp'
bits_pp :: [Bool] -> String
bits_pp :: [Bool] -> String
bits_pp = forall a b. (a -> b) -> [a] -> [b]
map Bool -> Char
bit_pp

-- | Generate /n/ place bit sequence for /x/.
gen_bitseq :: FiniteBits b => Int -> b -> [Bool]
gen_bitseq :: forall b. FiniteBits b => Int -> b -> [Bool]
gen_bitseq Int
n b
x =
    if forall b. FiniteBits b => b -> Int
finiteBitSize b
x forall a. Ord a => a -> a -> Bool
< Int
n
    then forall a. HasCallStack => String -> a
error String
"gen_bitseq"
    else forall a b. (a -> b) -> [a] -> [b]
map (forall a. Bits a => a -> Int -> Bool
testBit b
x) (forall a. [a] -> [a]
reverse [Int
0 .. Int
n forall a. Num a => a -> a -> a
- Int
1])

-- | Given bit sequence (most to least significant) generate 'Bits' value.
--
-- > :set -XBinaryLiterals
-- > pack_bitseq [True,False,True,False] == 0b1010
-- > pack_bitseq [True,False,False,True,False,False] == 0b100100
-- > 0b100100 == 36
pack_bitseq :: Bits i => [Bool] -> i
pack_bitseq :: forall i. Bits i => [Bool] -> i
pack_bitseq =
    forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\i
n (Int
k,Bool
b) -> if Bool
b then forall a. Bits a => a -> Int -> a
setBit i
n Int
k else i
n) forall a. Bits a => a
zeroBits forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall a. [a] -> [a]
reverse

-- | 'bits_pp' of 'gen_bitseq'.
--
-- > :set -XBinaryLiterals
-- > 0xF0 == 0b11110000
-- > gen_bitseq_pp 8 (0xF0::Int) == "11110000"
gen_bitseq_pp :: FiniteBits b => Int -> b -> String
gen_bitseq_pp :: forall b. FiniteBits b => Int -> b -> String
gen_bitseq_pp Int
n = [Bool] -> String
bits_pp forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. FiniteBits b => Int -> b -> [Bool]
gen_bitseq Int
n