module Basement.NormalForm ( NormalForm(..) , deepseq , force ) where import Basement.Compat.Base import Basement.Compat.C.Types import Basement.Compat.Natural import Basement.Types.OffsetSize import Basement.Types.Char7 import Basement.Types.Word128 (Word128) import Basement.Types.Word256 (Word256) import Basement.Bounded import Basement.Endianness -- | Data that can be fully evaluated in Normal Form -- class NormalForm a where toNormalForm :: a -> () deepseq :: NormalForm a => a -> b -> b deepseq a b = toNormalForm a `seq` b force :: NormalForm a => a -> a force a = toNormalForm a `seq` a ----- -- GHC / base types instance NormalForm Int8 where toNormalForm !_ = () instance NormalForm Int16 where toNormalForm !_ = () instance NormalForm Int32 where toNormalForm !_ = () instance NormalForm Int64 where toNormalForm !_ = () instance NormalForm Int where toNormalForm !_ = () instance NormalForm Integer where toNormalForm !_ = () instance NormalForm Word8 where toNormalForm !_ = () instance NormalForm Word16 where toNormalForm !_ = () instance NormalForm Word32 where toNormalForm !_ = () instance NormalForm Word64 where toNormalForm !_ = () instance NormalForm Word where toNormalForm !_ = () instance NormalForm Natural where toNormalForm !_ = () instance NormalForm Float where toNormalForm !_ = () instance NormalForm Double where toNormalForm !_ = () instance NormalForm Char where toNormalForm !_ = () instance NormalForm Bool where toNormalForm !_ = () instance NormalForm () where toNormalForm !_ = () ----- -- C Types instance NormalForm CChar where toNormalForm !_ = () instance NormalForm CUChar where toNormalForm !_ = () instance NormalForm CSChar where toNormalForm !_ = () instance NormalForm CShort where toNormalForm !_ = () instance NormalForm CUShort where toNormalForm !_ = () instance NormalForm CInt where toNormalForm !_ = () instance NormalForm CUInt where toNormalForm !_ = () instance NormalForm CLong where toNormalForm !_ = () instance NormalForm CULong where toNormalForm !_ = () instance NormalForm CLLong where toNormalForm !_ = () instance NormalForm CULLong where toNormalForm !_ = () instance NormalForm CFloat where toNormalForm !_ = () instance NormalForm CDouble where toNormalForm !_ = () instance NormalForm (Ptr a) where toNormalForm !_ = () ----- -- Basic Foundation primitive types instance NormalForm (Offset a) where toNormalForm !_ = () instance NormalForm (CountOf a) where toNormalForm !_ = () instance NormalForm Char7 where toNormalForm !_ = () instance NormalForm Word128 where toNormalForm !_ = () instance NormalForm Word256 where toNormalForm !_ = () instance NormalForm (Zn n) where toNormalForm = toNormalForm . unZn instance NormalForm (Zn64 n) where toNormalForm = toNormalForm . unZn64 ----- -- composed type instance NormalForm a => NormalForm (Maybe a) where toNormalForm Nothing = () toNormalForm (Just a) = toNormalForm a `seq` () instance (NormalForm l, NormalForm r) => NormalForm (Either l r) where toNormalForm (Left l) = toNormalForm l `seq` () toNormalForm (Right r) = toNormalForm r `seq` () instance NormalForm a => NormalForm (LE a) where toNormalForm (LE a) = toNormalForm a `seq` () instance NormalForm a => NormalForm (BE a) where toNormalForm (BE a) = toNormalForm a `seq` () instance NormalForm a => NormalForm [a] where toNormalForm [] = () toNormalForm (x:xs) = toNormalForm x `seq` toNormalForm xs instance (NormalForm a, NormalForm b) => NormalForm (a,b) where toNormalForm (a,b) = toNormalForm a `seq` toNormalForm b instance (NormalForm a, NormalForm b, NormalForm c) => NormalForm (a,b,c) where toNormalForm (a,b,c) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c instance (NormalForm a, NormalForm b, NormalForm c, NormalForm d) => NormalForm (a,b,c,d) where toNormalForm (a,b,c,d) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c `seq` toNormalForm d instance (NormalForm a, NormalForm b, NormalForm c, NormalForm d, NormalForm e) => NormalForm (a,b,c,d,e) where toNormalForm (a,b,c,d,e) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c `seq` toNormalForm d `seq` toNormalForm e instance (NormalForm a, NormalForm b, NormalForm c, NormalForm d, NormalForm e, NormalForm f) => NormalForm (a,b,c,d,e,f) where toNormalForm (a,b,c,d,e,f) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c `seq` toNormalForm d `seq` toNormalForm e `seq` toNormalForm f instance (NormalForm a, NormalForm b, NormalForm c, NormalForm d, NormalForm e, NormalForm f, NormalForm g) => NormalForm (a,b,c,d,e,f,g) where toNormalForm (a,b,c,d,e,f,g) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c `seq` toNormalForm d `seq` toNormalForm e `seq` toNormalForm f `seq` toNormalForm g instance (NormalForm a, NormalForm b, NormalForm c, NormalForm d, NormalForm e, NormalForm f, NormalForm g, NormalForm h) => NormalForm (a,b,c,d,e,f,g,h) where toNormalForm (a,b,c,d,e,f,g,h) = toNormalForm a `seq` toNormalForm b `seq` toNormalForm c `seq` toNormalForm d `seq` toNormalForm e `seq` toNormalForm f `seq` toNormalForm g `seq` toNormalForm h