{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Nix.Thunk where
import Control.Exception ( Exception )
import Control.Monad.Trans.Class ( MonadTrans(..) )
import Control.Monad.Trans.Except
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State
import Control.Monad.Trans.Writer
import Data.Typeable ( Typeable )
class ( Monad m
, Eq (ThunkId m)
, Ord (ThunkId m)
, Show (ThunkId m)
, Typeable (ThunkId m)
)
=> MonadThunkId m where
type ThunkId m :: *
freshId :: m (ThunkId m)
default freshId
:: ( MonadThunkId m'
, MonadTrans t
, m ~ t m'
, ThunkId m ~ ThunkId m'
)
=> m (ThunkId m)
freshId = m' (ThunkId m) -> t m' (ThunkId m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m' (ThunkId m)
forall (m :: * -> *). MonadThunkId m => m (ThunkId m)
freshId
instance MonadThunkId m => MonadThunkId (ReaderT r m) where
type ThunkId (ReaderT r m) = ThunkId m
instance (Monoid w, MonadThunkId m) => MonadThunkId (WriterT w m) where
type ThunkId (WriterT w m) = ThunkId m
instance MonadThunkId m => MonadThunkId (ExceptT e m) where
type ThunkId (ExceptT e m) = ThunkId m
instance MonadThunkId m => MonadThunkId (StateT s m) where
type ThunkId (StateT s m) = ThunkId m
class MonadThunkId m => MonadThunk t m a | t -> m, t -> a where
thunk :: m a -> m t
thunkId :: t -> ThunkId m
queryM :: t -> m r -> (a -> m r) -> m r
force :: t -> (a -> m r) -> m r
forceEff :: t -> (a -> m r) -> m r
further :: t -> (m a -> m a) -> m t
newtype ThunkLoop = ThunkLoop String
deriving Typeable
instance Show ThunkLoop where
show :: ThunkLoop -> String
show (ThunkLoop i :: String
i) = "ThunkLoop " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i
instance Exception ThunkLoop