{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Binrep.BLen
( BLen(blen)
, blenGenericNonSum, blenGenericSum, blenGenericSumRaw
, ViaCBLen(..), cblen
) where
import Binrep.CBLen
import GHC.TypeNats
import Binrep.Common.Class.TypeErrors ( ENoSum, ENoEmpty )
import GHC.TypeLits ( TypeError )
import Data.Void
import Data.ByteString qualified as B
import Data.Word
import Data.Int
import Binrep.Util.ByteOrder
import Data.Monoid qualified as Monoid
import GHC.Generics
import Generic.Data.Function.FoldMap
import Generic.Data.MetaParse.Cstr ( Raw, ParseCstrTo )
import Generic.Type.Assert
import Binrep.Common.Via.Generically.NonSum
import Rerefined.Refine
import Rerefined.Predicate.Logical.And
class BLen a where
blen :: a -> Int
instance GenericFoldMap BLen where
type GenericFoldMapM BLen = Monoid.Sum Int
type GenericFoldMapC BLen a = BLen a
genericFoldMapF :: forall a. GenericFoldMapC BLen a => a -> GenericFoldMapM BLen
genericFoldMapF = Int -> Sum Int
forall a. a -> Sum a
Monoid.Sum (Int -> Sum Int) -> (a -> Int) -> a -> Sum Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. BLen a => a -> Int
blen
blenGenericNonSum
:: forall a
. ( Generic a, GFoldMapNonSum BLen (Rep a)
, GAssertNotVoid a, GAssertNotSum a
) => a -> Int
blenGenericNonSum :: forall a.
(Generic a, GFoldMapNonSum BLen (Rep a), GAssertNotVoid a,
GAssertNotSum a) =>
a -> Int
blenGenericNonSum = Sum Int -> Int
forall a. Sum a -> a
Monoid.getSum (Sum Int -> Int) -> (a -> Sum Int) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (tag :: k) a.
(Generic a, GFoldMapNonSum tag (Rep a)) =>
a -> GenericFoldMapM tag
forall (tag :: Type -> Constraint) a.
(Generic a, GFoldMapNonSum tag (Rep a)) =>
a -> GenericFoldMapM tag
genericFoldMapNonSum @BLen
instance
( Generic a, GFoldMapNonSum BLen (Rep a)
, GAssertNotVoid a, GAssertNotSum a
) => BLen (GenericallyNonSum a) where
blen :: GenericallyNonSum a -> Int
blen = a -> Int
forall a.
(Generic a, GFoldMapNonSum BLen (Rep a), GAssertNotVoid a,
GAssertNotSum a) =>
a -> Int
blenGenericNonSum (a -> Int)
-> (GenericallyNonSum a -> a) -> GenericallyNonSum a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenericallyNonSum a -> a
forall a. GenericallyNonSum a -> a
unGenericallyNonSum
blenGenericSum
:: forall sumtag a
. ( Generic a, GFoldMapSum BLen sumtag (Rep a)
, GAssertNotVoid a, GAssertSum a
) => ParseCstrTo sumtag Int -> a -> Int
blenGenericSum :: forall {k} (sumtag :: k) a.
(Generic a, GFoldMapSum BLen sumtag (Rep a), GAssertNotVoid a,
GAssertSum a) =>
ParseCstrTo sumtag Int -> a -> Int
blenGenericSum ParseCstrTo sumtag Int
f =
Sum Int -> Int
forall a. Sum a -> a
Monoid.getSum (Sum Int -> Int) -> (a -> Sum Int) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k1} {k2} (tag :: k1) (sumtag :: k2) a.
(Generic a, GFoldMapSum tag sumtag (Rep a)) =>
ParseCstrTo sumtag (GenericFoldMapM tag)
-> a -> GenericFoldMapM tag
forall (tag :: Type -> Constraint) (sumtag :: k) a.
(Generic a, GFoldMapSum tag sumtag (Rep a)) =>
ParseCstrTo sumtag (GenericFoldMapM tag)
-> a -> GenericFoldMapM tag
genericFoldMapSum @BLen @sumtag (\Proxy# x
p -> Int -> Sum Int
forall a. a -> Sum a
Monoid.Sum (Proxy# x -> Int
ParseCstrTo sumtag Int
f Proxy# x
p))
blenGenericSumRaw
:: forall a
. ( Generic a, GFoldMapSum BLen Raw (Rep a)
, GAssertNotVoid a, GAssertSum a
) => (String -> Int) -> a -> Int
blenGenericSumRaw :: forall a.
(Generic a, GFoldMapSum BLen Raw (Rep a), GAssertNotVoid a,
GAssertSum a) =>
(String -> Int) -> a -> Int
blenGenericSumRaw String -> Int
f =
Sum Int -> Int
forall a. Sum a -> a
Monoid.getSum (Sum Int -> Int) -> (a -> Sum Int) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (tag :: k) a.
(Generic a, GFoldMapSum tag Raw (Rep a)) =>
(String -> GenericFoldMapM tag) -> a -> GenericFoldMapM tag
forall (tag :: Type -> Constraint) a.
(Generic a, GFoldMapSum tag Raw (Rep a)) =>
(String -> GenericFoldMapM tag) -> a -> GenericFoldMapM tag
genericFoldMapSumRaw @BLen (Int -> Sum Int
forall a. a -> Sum a
Monoid.Sum (Int -> Sum Int) -> (String -> Int) -> String -> Sum Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Int
f)
instance BLen (Refined pr (Refined pl a))
=> BLen (Refined (pl `And` pr) a) where
blen :: Refined (And pl pr) a -> Int
blen = Refined pr (Refined pl a) -> Int
forall a. BLen a => a -> Int
blen (Refined pr (Refined pl a) -> Int)
-> (Refined (And pl pr) a -> Refined pr (Refined pl a))
-> Refined (And pl pr) a
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (p :: k1). a -> Refined p a
forall {k} a (p :: k). a -> Refined p a
unsafeRefine @_ @pr (Refined pl a -> Refined pr (Refined pl a))
-> (Refined (And pl pr) a -> Refined pl a)
-> Refined (And pl pr) a
-> Refined pr (Refined pl a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (p :: k). a -> Refined p a
forall {k} a (p :: k). a -> Refined p a
unsafeRefine @_ @pl (a -> Refined pl a)
-> (Refined (And pl pr) a -> a)
-> Refined (And pl pr) a
-> Refined pl a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Refined (And pl pr) a -> a
forall {k} (p :: k) a. Refined p a -> a
unrefine
instance TypeError ENoEmpty => BLen Void where blen :: Void -> Int
blen = Void -> Int
forall a. HasCallStack => a
undefined
instance TypeError ENoSum => BLen (Either a b) where blen :: Either a b -> Int
blen = Either a b -> Int
forall a. HasCallStack => a
undefined
instance BLen () where blen :: () -> Int
blen () = Int
0
instance (BLen l, BLen r) => BLen (l, r) where blen :: (l, r) -> Int
blen (l
l, r
r) = l -> Int
forall a. BLen a => a -> Int
blen l
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ r -> Int
forall a. BLen a => a -> Int
blen r
r
instance BLen a => BLen [a] where blen :: [a] -> Int
blen = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: Type -> Type) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> ([a] -> [Int]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Int) -> [a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map a -> Int
forall a. BLen a => a -> Int
blen
instance BLen B.ByteString where blen :: ByteString -> Int
blen = ByteString -> Int
B.length
deriving via ViaCBLen Word8 instance BLen Word8
deriving via ViaCBLen Int8 instance BLen Int8
deriving via ViaCBLen Word16 instance BLen Word16
deriving via ViaCBLen Int16 instance BLen Int16
deriving via ViaCBLen Word32 instance BLen Word32
deriving via ViaCBLen Int32 instance BLen Int32
deriving via ViaCBLen Word64 instance BLen Word64
deriving via ViaCBLen Int64 instance BLen Int64
deriving via ViaCBLen (ByteOrdered end a)
instance KnownNat (CBLen a) => BLen (ByteOrdered end a)
newtype ViaCBLen a = ViaCBLen { forall a. ViaCBLen a -> a
unViaCBLen :: a }
instance KnownNat (CBLen a) => BLen (ViaCBLen a) where blen :: ViaCBLen a -> Int
blen ViaCBLen a
_ = forall a. KnownNat (CBLen a) => Int
forall {k} (a :: k). KnownNat (CBLen a) => Int
cblen @a