{-# LANGUAGE GHC2024 #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RequiredTypeArguments #-} import Data.Typeable (Typeable, cast) data SomeStorable where Storage :: MyStorable a => a -> SomeStorable class Typeable a => MyStorable a where sizeOf :: forall b -> b ~ a => Int instance MyStorable Bool where sizeOf _ = 1 instance MyStorable Int where sizeOf _ = 8 testMe :: forall a. MyStorable a => a -> Int; testMe _ = sizeOf a testMe2 :: forall a. MyStorable a => Int; testMe2 = sizeOf a testMe3 :: SomeStorable -> Int; testMe3 (Storage (_ :: a)) = sizeOf a pattern MyInt :: Int; pattern MyInt = 42 main :: IO () main = do print $ testMe True print $ testMe MyInt print $ testMe2 @Bool print $ testMe2 @Int print $ testMe3 (Storage True) print $ testMe3 (Storage MyInt)