{-# LANGUAGE Unsafe #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} -- For Determinism {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE KindSignatures #-} {-| This module is /not/ Safe Haskell; as an end-user, you shouldn't ever need to import it. It is exposed only because it is necessary for implementing /new/ LVar types that will live in their own, separate packages. -} module Control.LVish.Internal ( -- * Type-safe wrappers around internal components Par(..), LVar(..), Determinism(..), QPar, -- * Unsafe conversions and lifting unWrapPar, unsafeRunPar, unsafeConvert, state, liftIO ) where import Control.Monad.IO.Class import Control.LVish.MonadToss import Control.Applicative import qualified Control.LVish.SchedIdempotent as L import Control.LVish.DeepFrz.Internal (Frzn, Trvrsbl) import qualified Data.Foldable as F import Data.List (sort) {-# INLINE state #-} {-# INLINE unsafeConvert #-} {-# INLINE unWrapPar #-} -------------------------------------------------------------------------------- -- | This datatype is promoted to type-level (@DataKinds@ extension) -- and used to indicate whether a `Par` computation is -- guaranteed-deterministic, or only quasi-deterministic (i.e., might -- throw `NonDeterminismExn`). data Determinism = Det | QuasiDet deriving Show -- | The type of parallel computations. A computation @Par d s a@ may or may not be -- deterministic based on the setting of the `d` parameter (of kind `Determinism`). -- The `s` parameter is for preventing the escape of @LVar@s from @Par@ computations -- (just like the @ST@ monad). -- -- Implementation note: This is a wrapper around the internal `Par` type, only with more type parameters. newtype Par :: Determinism -> * -> * -> * where WrapPar :: L.Par a -> Par d s a deriving (Monad, Functor, Applicative) -- | A shorthand for quasi-deterministic `Par` computations. type QPar = Par QuasiDet -- | The generic representation of LVars used by the scheduler. The -- end-user can't actually do anything with these and should not try -- to. -- LK: I don't care if we use `a` and `d` or `all` and `delt`, but why -- not be consistent between here and SchedIdempotent.hs? Also, what -- does `all` mean? newtype LVar s all delt = WrapLVar { unWrapLVar :: L.LVar all delt } -- | Unsafe: drops type information to go from the safe `Par` monad to -- the internal, dangerous one. unWrapPar :: Par d s a -> L.Par a unWrapPar (WrapPar p) = p -- | This is cheating! It pays no attention to session sealing (@s@) or to the -- determinism level (@d@). unsafeRunPar :: Par d s a -> a unsafeRunPar p = L.runPar (unWrapPar p) -- | Extract the state of an LVar. This should only be used by implementations of -- new LVar data structures. state :: LVar s a d -> a state = L.state . unWrapLVar -- | Ignore the extra type annotations regarding both determinism and session-sealing. unsafeConvert :: Par d1 s1 a -> Par d2 s2 a unsafeConvert (WrapPar p) = (WrapPar p) instance MonadIO (Par d s) where liftIO = WrapPar . L.liftIO instance MonadToss (Par d s) where toss = WrapPar L.toss