recover-rtti-0.1.0.0: tests/Test/RecoverRTTI/UserDefined.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UnboxedTuples #-}
-- | Just some examples of user-defined types
module Test.RecoverRTTI.UserDefined (
NonRecursive(..)
, Recursive(..)
, recursiveFromList
, ContainsUnlifted -- opaque
, exampleContainsUnlifted
) where
import GHC.Generics
import GHC.IO
import GHC.Prim
{-------------------------------------------------------------------------------
User-defined datatypes
-------------------------------------------------------------------------------}
-- | Example of a non-recursive user-defined type
data NonRecursive a = NR1 Int | NR2 a Bool
deriving (Show, Eq, Generic, Functor, Foldable, Traversable)
-- | Example of a recursive user-defined type
data Recursive a = RNil | RCons a (Recursive a)
deriving (Show, Eq, Generic, Functor, Foldable, Traversable)
recursiveFromList :: [a] -> Recursive a
recursiveFromList = foldr RCons RNil
{-------------------------------------------------------------------------------
Example of a type with an unlifted value
Most instances here don't really make much sense; this is just here to
verify we don't crash when coming across unlifted values
-------------------------------------------------------------------------------}
-- | Example of a user-defined type containing something unlifted
data ContainsUnlifted a = NothingHere | ContainsUnlifted (MutableArray# RealWorld Int) a
deriving (Functor, Foldable, Traversable)
-- We can't derive a Generic instance, we must produce just enough info so that
-- we can do the right type casts
instance Generic (ContainsUnlifted a) where
type Rep (ContainsUnlifted a) = Rep_ContainsUnlifted
from = error "'from' not defined for ContainsUnlifted"
to = error "'to' not defined for ContainsUnlifted"
-- We don't bother specifiying the arguments to the constructors
type Rep_ContainsUnlifted =
M1 D ('MetaData "ContainsUnlifted" "Test.RecoverRTTI.UserDefined" "main" 'False)
( M1 C ('MetaCons "NothingHere" 'PrefixI 'False) U1
:+:
M1 C ('MetaCons "ContainsUnlifted" 'PrefixI 'False) U1
)
instance Show a => Show (ContainsUnlifted a) where
showsPrec _ NothingHere =
showString "NothingHere"
showsPrec p (ContainsUnlifted _ x) = showParen (p >= 11) $
showString "ContainsUnlifted "
. showsPrec 11 x
instance Eq (ContainsUnlifted a) where
_ == _ = True
exampleContainsUnlifted :: ContainsUnlifted ()
{-# NOINLINE exampleContainsUnlifted #-}
exampleContainsUnlifted = unsafePerformIO $ IO $ \world ->
let !(# world', arr #) = newArray# 5# 0 world
in (# world', ContainsUnlifted arr () #)