module Codec.Elias.Natural
(
encodeGamma
, decodeGamma
, encodeDelta
, decodeDelta
, encodeOmega
, decodeOmega
) where
import Data.Bifunctor (Bifunctor(first))
import Codec.Arithmetic.Variety.BitVec (BitVec)
import qualified Codec.Elias as E
boundsError :: a
boundsError :: forall a. a
boundsError = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"Elias.Natural: negative number"
encodeGamma :: Integer -> BitVec
encodeGamma :: Integer -> BitVec
encodeGamma Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = Integer -> BitVec
E.encodeGamma (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1)
| Bool
otherwise = BitVec
forall a. a
boundsError
decodeGamma :: BitVec -> Maybe (Integer, BitVec)
decodeGamma :: BitVec -> Maybe (Integer, BitVec)
decodeGamma = ((Integer, BitVec) -> (Integer, BitVec))
-> Maybe (Integer, BitVec) -> Maybe (Integer, BitVec)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Integer -> Integer) -> (Integer, BitVec) -> (Integer, BitVec)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+(-Integer
1))) (Maybe (Integer, BitVec) -> Maybe (Integer, BitVec))
-> (BitVec -> Maybe (Integer, BitVec))
-> BitVec
-> Maybe (Integer, BitVec)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BitVec -> Maybe (Integer, BitVec)
E.decodeGamma
encodeDelta :: Integer -> BitVec
encodeDelta :: Integer -> BitVec
encodeDelta Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = Integer -> BitVec
E.encodeDelta (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1)
| Bool
otherwise = BitVec
forall a. a
boundsError
decodeDelta :: BitVec -> Maybe (Integer, BitVec)
decodeDelta :: BitVec -> Maybe (Integer, BitVec)
decodeDelta = ((Integer, BitVec) -> (Integer, BitVec))
-> Maybe (Integer, BitVec) -> Maybe (Integer, BitVec)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Integer -> Integer) -> (Integer, BitVec) -> (Integer, BitVec)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+(-Integer
1))) (Maybe (Integer, BitVec) -> Maybe (Integer, BitVec))
-> (BitVec -> Maybe (Integer, BitVec))
-> BitVec
-> Maybe (Integer, BitVec)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BitVec -> Maybe (Integer, BitVec)
E.decodeDelta
encodeOmega :: Integer -> BitVec
encodeOmega :: Integer -> BitVec
encodeOmega Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = Integer -> BitVec
E.encodeOmega Integer
n
| Bool
otherwise = BitVec
forall a. a
boundsError
decodeOmega :: BitVec -> Maybe (Integer, BitVec)
decodeOmega :: BitVec -> Maybe (Integer, BitVec)
decodeOmega = ((Integer, BitVec) -> (Integer, BitVec))
-> Maybe (Integer, BitVec) -> Maybe (Integer, BitVec)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Integer -> Integer) -> (Integer, BitVec) -> (Integer, BitVec)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+(-Integer
1))) (Maybe (Integer, BitVec) -> Maybe (Integer, BitVec))
-> (BitVec -> Maybe (Integer, BitVec))
-> BitVec
-> Maybe (Integer, BitVec)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BitVec -> Maybe (Integer, BitVec)
E.decodeOmega