module Control.Monad.STLike.Internal where import Control.DeepSeq import Control.Monad import Data.Foldable(Foldable, toList) import Foreign -- | Regioned variables. -- A regioned variable is /safe/ i.e. no references to -- it may escape the current IOS. newtype Regioned s t = R t instance Monad (Regioned s) where return = R _ >> b = b (R v) >>= f = f v instance Functor (Regioned s) where fmap f (R v) = R (f v) -- | Run a computation on regioned data -- and return the result in a strict fashion. runRegion :: (NotShared ty, RegionMonad m region s) => Regioned s ty -> STLike m region ty runRegion = runRegionImpl class NFData ty => NotShared ty where runRegionImpl :: RegionMonad m region s => Regioned s ty -> STLike m region ty runRegionImpl (R v) = v `deepseq` return v instance NotShared Bool instance NotShared Char instance NotShared Double instance NotShared Float instance NotShared Int instance NotShared Int8 instance NotShared Int16 instance NotShared Int32 instance NotShared Int64 instance NotShared Integer instance NotShared Word instance NotShared Word8 instance NotShared Word16 instance NotShared Word32 instance NotShared Word64 instance NotShared () --instance NotShared IntSet instance NotShared a => NotShared ([] a) --instance (Integral a, NotShared a) => NotShared (Ratio a) --instance (RealFloat a, NotShared a) => NotShared (Complex a) instance NotShared a => NotShared (Maybe a) --NotShared a => NotShared (IntMap a) --NotShared a => NotShared (Tree a) --NotShared a => NotShared (Set a) instance (NotShared a, NotShared b) => NotShared (Either a b) instance (NotShared a, NotShared b) => NotShared ((,) a b) --(Ix a, NotShared a, NotShared b) => NotShared (Array a b) --(NotShared k, NotShared a) => NotShared (Map k a) instance (NotShared a, NotShared b, NotShared c) => NotShared ((,,) a b c) instance (NotShared a, NotShared b, NotShared c, NotShared d) => NotShared ((,,,) a b c d) instance (NotShared a1, NotShared a2, NotShared a3, NotShared a4, NotShared a5) => NotShared ((,,,,) a1 a2 a3 a4 a5) --instance NotShared B.ByteString where -- runRegion (R bs) = return $! B.copy bs unsafeRemoveRegion :: RegionMonad m region s => Regioned s r -> STLike m region r unsafeRemoveRegion (R x) = return x unfoldRegion :: Foldable t => Regioned s (t a) -> [Regioned s a] unfoldRegion (R t) = map R (toList t) newtype STLike m s t = STLike (m t) class Monad m => STLikeImpl (m :: * -> *) instance STLikeImpl m => Monad (STLike m s) where (STLike a) >> (STLike b) = STLike (a >> b) (STLike a) >>= b = STLike $ do v <- a let STLike r = b v r return x = STLike (return x) instance (STLikeImpl m) => Functor (STLike m s) where fmap f (STLike m) = STLike (liftM f m) data (:<) a b class STLikeImpl m => RegionMonad (m :: * -> *) region s instance STLikeImpl m => RegionMonad m s s instance (STLikeImpl m, reg `TypeCast` (any :< rest), RegionMonad m rest s) => RegionMonad m reg s -- see http://okmij.org/ftp/Haskell/typecast.html class TypeCast a b | a -> b, b->a where typeCast :: a -> b class TypeCast' t a b | t a -> b, t b -> a where typeCast' :: t->a->b class TypeCast'' t a b | t a -> b, t b -> a where typeCast'' :: t->a->b instance TypeCast' () a b => TypeCast a b where typeCast x = typeCast' () x instance TypeCast'' t a b => TypeCast' t a b where typeCast' = typeCast'' instance TypeCast'' () a a where typeCast'' _ x = x