{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ExistentialQuantification #-}
module OAlg.Control.HNFData
( HNFValue(..), fromHNFValue
, HNFData(..), hnfValue
)
where
import Control.Exception
data HNFValue x = HNFValue x | forall e . Exception e => Failure e
deriving instance Show x => Show (HNFValue x)
instance Functor HNFValue where
fmap :: forall a b. (a -> b) -> HNFValue a -> HNFValue b
fmap a -> b
f (HNFValue a
x) = forall x. x -> HNFValue x
HNFValue (a -> b
f a
x)
fmap a -> b
_ (Failure e
e) = forall x e. Exception e => e -> HNFValue x
Failure e
e
fromHNFValue :: HNFValue x -> x
fromHNFValue :: forall x. HNFValue x -> x
fromHNFValue HNFValue x
hvx = case HNFValue x
hvx of
HNFValue x
x -> x
x
Failure e
e -> forall a e. Exception e => e -> a
throw e
e
class HNFData x where
rhnf :: x -> ()
hnfValue :: HNFData x => x -> IO (HNFValue x)
hnfValue :: forall x. HNFData x => x -> IO (HNFValue x)
hnfValue x
x = case forall x. HNFData x => x -> ()
rhnf x
x of
() -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall x. x -> HNFValue x
HNFValue x
x)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` (\(SomeException
e :: SomeException) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall x e. Exception e => e -> HNFValue x
Failure SomeException
e))
instance HNFData () where
rhnf :: () -> ()
rhnf () = ()
instance HNFData Bool where
rhnf :: Bool -> ()
rhnf Bool
False = ()
rhnf Bool
_ = ()
instance HNFData [x] where
rhnf :: [x] -> ()
rhnf [x]
xs = case [x]
xs of
[] -> ()
[x]
_ -> ()