{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}
module Binrep.BLen
( module Binrep.BLen
, module Binrep.BLen.Internal.AsBLen
) where
import Binrep.BLen.Internal.AsBLen
import Binrep.Util ( natVal'' )
import GHC.TypeLits
import Data.ByteString qualified as B
import Data.Word
import Data.Int
import Data.Void ( Void, absurd )
type BLenT = Int
class BLen a where
blen :: a -> BLenT
default blen :: KnownNat (CBLen a) => a -> BLenT
blen a
_ = forall a (n :: Natural). (n ~ CBLen a, KnownNat n) => BLenT
cblen @a
type CBLen a :: Natural
type CBLen a =
TypeError
( 'Text "No CBLen associated family instance defined for "
':<>: 'ShowType a
)
typeNatToBLen :: forall n. KnownNat n => BLenT
typeNatToBLen :: forall (n :: Natural). KnownNat n => BLenT
typeNatToBLen = forall a. AsBLen a => Natural -> a
natToBLen forall a b. (a -> b) -> a -> b
$ forall (a :: Natural). KnownNat a => Natural
natVal'' @n
{-# INLINE typeNatToBLen #-}
cblen :: forall a n. (n ~ CBLen a, KnownNat n) => BLenT
cblen :: forall a (n :: Natural). (n ~ CBLen a, KnownNat n) => BLenT
cblen = forall (n :: Natural). KnownNat n => BLenT
typeNatToBLen @n
{-# INLINE cblen #-}
instance BLen Void where
blen :: Void -> BLenT
blen = forall a. Void -> a
absurd
instance BLen a => BLen [a] where
blen :: [a] -> BLenT
blen = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. BLen a => a -> BLenT
blen
instance (BLen a, BLen b) => BLen (a, b) where
blen :: (a, b) -> BLenT
blen (a
a, b
b) = forall a. BLen a => a -> BLenT
blen a
a forall a. Num a => a -> a -> a
+ forall a. BLen a => a -> BLenT
blen b
b
instance BLen B.ByteString where
blen :: ByteString -> BLenT
blen = forall a. AsBLen a => BLenT -> a
posIntToBLen forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> BLenT
B.length
instance BLen Word8 where type CBLen Word8 = 1
instance BLen Int8 where type CBLen Int8 = 1
instance BLen Word16 where type CBLen Word16 = 2
instance BLen Int16 where type CBLen Int16 = 2
instance BLen Word32 where type CBLen Word32 = 4
instance BLen Int32 where type CBLen Int32 = 4
instance BLen Word64 where type CBLen Word64 = 8
instance BLen Int64 where type CBLen Int64 = 8
newtype WithCBLen a = WithCBLen { forall a. WithCBLen a -> a
unWithCBLen :: a }
instance KnownNat (CBLen a) => BLen (WithCBLen [a]) where
blen :: WithCBLen [a] -> BLenT
blen (WithCBLen [a]
l) = forall a (n :: Natural). (n ~ CBLen a, KnownNat n) => BLenT
cblen @a forall a. Num a => a -> a -> a
* forall (t :: * -> *) a. Foldable t => t a -> BLenT
length [a]
l
instance KnownNat (CBLen a + CBLen b) => BLen (WithCBLen (a, b)) where
type CBLen (WithCBLen (a, b)) = CBLen a + CBLen b