module Control.DeeperSeq where
import Foreign
import Control.DeepSeq
type family Result a where
Result (IO a) = Result a
Result (b -> a) = Result a
Result a = a
type family SetResult a b where
SetResult x (IO a) = IO (SetResult x a)
SetResult x (b -> a) = b -> SetResult x a
SetResult x y = x
class (SetResult (Result a) a ~ a) => MapResult a where
mapResult :: (Result a -> b) -> a -> SetResult b a
instance MapResult Char where mapResult = id
instance MapResult Double where mapResult = id
instance MapResult Float where mapResult = id
instance MapResult Bool where mapResult = id
instance MapResult Int where mapResult = id
instance MapResult Int8 where mapResult = id
instance MapResult Int16 where mapResult = id
instance MapResult Int32 where mapResult = id
instance MapResult Int64 where mapResult = id
instance MapResult Word where mapResult = id
instance MapResult Word8 where mapResult = id
instance MapResult Word16 where mapResult = id
instance MapResult Word32 where mapResult = id
instance MapResult Word64 where mapResult = id
instance MapResult (Ptr a) where mapResult = id
instance MapResult (FunPtr a) where mapResult = id
instance MapResult (StablePtr a) where mapResult = id
instance MapResult () where mapResult = id
instance MapResult (a, b) where mapResult = id
instance MapResult (a, b, c) where mapResult = id
instance MapResult (a, b, c, d) where mapResult = id
instance MapResult b => MapResult (a -> b) where mapResult = fmap . mapResult
instance MapResult a => MapResult (IO a) where mapResult = fmap . mapResult
deeperSeq :: (NFData a, MapResult b) => a -> b -> b
deeperSeq a b = mapResult (deepseq a) b