2019-03-17 00:23:40 +01:00
|
|
|
{-# LANGUAGE DefaultSignatures #-}
|
2018-04-07 21:02:50 +02:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2018-04-09 09:52:10 +02:00
|
|
|
{-# LANGUAGE FunctionalDependencies #-}
|
2019-03-11 16:04:15 +01:00
|
|
|
{-# LANGUAGE TypeFamilies #-}
|
2019-03-17 00:23:40 +01:00
|
|
|
{-# LANGUAGE UndecidableInstances #-}
|
2019-01-08 19:24:40 +01:00
|
|
|
|
2018-04-07 21:02:50 +02:00
|
|
|
module Nix.Thunk where
|
|
|
|
|
2019-03-17 22:47:38 +01:00
|
|
|
import Control.Exception ( Exception )
|
|
|
|
import Control.Monad.Trans.Class ( MonadTrans(..) )
|
2019-03-22 23:16:01 +01:00
|
|
|
import Control.Monad.Trans.Except
|
|
|
|
import Control.Monad.Trans.Reader
|
|
|
|
import Control.Monad.Trans.State
|
|
|
|
import Control.Monad.Trans.Writer
|
2019-03-17 22:47:38 +01:00
|
|
|
import Data.Typeable ( Typeable )
|
2018-11-16 20:04:14 +01:00
|
|
|
|
2019-03-17 00:23:40 +01:00
|
|
|
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 = lift freshId
|
|
|
|
|
2019-03-22 23:16:01 +01:00
|
|
|
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
|
|
|
|
|
2019-03-18 19:41:46 +01:00
|
|
|
class MonadThunkId m => MonadThunk t m a | t -> m, t -> a where
|
2019-03-22 23:16:01 +01:00
|
|
|
thunk :: m a -> m t
|
|
|
|
|
|
|
|
-- | Return an identifier for the thunk unless it is a pure value (i.e.,
|
|
|
|
-- strictly an encapsulation of some 'a' without any additional
|
|
|
|
-- structure). For pure values represented as thunks, returns Nothing.
|
|
|
|
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
|
|
|
|
|
|
|
|
-- | Modify the action to be performed by the thunk. For some implicits
|
|
|
|
-- this modifies the thunk, for others it may create a new thunk.
|
|
|
|
further :: t -> (m a -> m a) -> m t
|
2018-04-07 21:02:50 +02:00
|
|
|
|
2019-03-17 00:23:40 +01:00
|
|
|
newtype ThunkLoop = ThunkLoop String -- contains rendering of ThunkId
|
2019-03-22 23:16:01 +01:00
|
|
|
deriving Typeable
|
2019-03-17 00:23:40 +01:00
|
|
|
|
|
|
|
instance Show ThunkLoop where
|
2019-03-17 22:47:38 +01:00
|
|
|
show (ThunkLoop i) = "ThunkLoop " ++ i
|
2018-04-24 11:14:27 +02:00
|
|
|
|
2018-05-02 02:33:17 +02:00
|
|
|
instance Exception ThunkLoop
|