{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -Wno-orphans #-}

module Nix.Fresh where

import           Control.Applicative
import           Control.Monad.Base
import           Control.Monad.Catch
import           Control.Monad.Except
#if !MIN_VERSION_base(4,13,0)
import           Control.Monad.Fail
#endif
import           Control.Monad.Reader
import           Control.Monad.Ref
import           Control.Monad.ST
import           Data.Typeable

import           Nix.Var
import           Nix.Thunk

newtype FreshIdT i m a = FreshIdT { FreshIdT i m a -> ReaderT (Var m i) m a
unFreshIdT :: ReaderT (Var m i) m a }
  deriving
    ( a -> FreshIdT i m b -> FreshIdT i m a
(a -> b) -> FreshIdT i m a -> FreshIdT i m b
(forall a b. (a -> b) -> FreshIdT i m a -> FreshIdT i m b)
-> (forall a b. a -> FreshIdT i m b -> FreshIdT i m a)
-> Functor (FreshIdT i m)
forall a b. a -> FreshIdT i m b -> FreshIdT i m a
forall a b. (a -> b) -> FreshIdT i m a -> FreshIdT i m b
forall i (m :: * -> *) a b.
Functor m =>
a -> FreshIdT i m b -> FreshIdT i m a
forall i (m :: * -> *) a b.
Functor m =>
(a -> b) -> FreshIdT i m a -> FreshIdT i m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> FreshIdT i m b -> FreshIdT i m a
$c<$ :: forall i (m :: * -> *) a b.
Functor m =>
a -> FreshIdT i m b -> FreshIdT i m a
fmap :: (a -> b) -> FreshIdT i m a -> FreshIdT i m b
$cfmap :: forall i (m :: * -> *) a b.
Functor m =>
(a -> b) -> FreshIdT i m a -> FreshIdT i m b
Functor
    , Functor (FreshIdT i m)
a -> FreshIdT i m a
Functor (FreshIdT i m) =>
(forall a. a -> FreshIdT i m a)
-> (forall a b.
    FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b)
-> (forall a b c.
    (a -> b -> c)
    -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c)
-> (forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b)
-> (forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a)
-> Applicative (FreshIdT i m)
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a
FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b
(a -> b -> c) -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c
forall a. a -> FreshIdT i m a
forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a
forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
forall a b.
FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b
forall a b c.
(a -> b -> c) -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c
forall i (m :: * -> *). Applicative m => Functor (FreshIdT i m)
forall i (m :: * -> *) a. Applicative m => a -> FreshIdT i m a
forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a
forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b
forall i (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a
$c<* :: forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m a
*> :: FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
$c*> :: forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
liftA2 :: (a -> b -> c) -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c
$cliftA2 :: forall i (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m c
<*> :: FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b
$c<*> :: forall i (m :: * -> *) a b.
Applicative m =>
FreshIdT i m (a -> b) -> FreshIdT i m a -> FreshIdT i m b
pure :: a -> FreshIdT i m a
$cpure :: forall i (m :: * -> *) a. Applicative m => a -> FreshIdT i m a
$cp1Applicative :: forall i (m :: * -> *). Applicative m => Functor (FreshIdT i m)
Applicative
    , Applicative (FreshIdT i m)
FreshIdT i m a
Applicative (FreshIdT i m) =>
(forall a. FreshIdT i m a)
-> (forall a. FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a)
-> (forall a. FreshIdT i m a -> FreshIdT i m [a])
-> (forall a. FreshIdT i m a -> FreshIdT i m [a])
-> Alternative (FreshIdT i m)
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
FreshIdT i m a -> FreshIdT i m [a]
FreshIdT i m a -> FreshIdT i m [a]
forall a. FreshIdT i m a
forall a. FreshIdT i m a -> FreshIdT i m [a]
forall a. FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
forall i (m :: * -> *). Alternative m => Applicative (FreshIdT i m)
forall i (m :: * -> *) a. Alternative m => FreshIdT i m a
forall i (m :: * -> *) a.
Alternative m =>
FreshIdT i m a -> FreshIdT i m [a]
forall i (m :: * -> *) a.
Alternative m =>
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
forall (f :: * -> *).
Applicative f =>
(forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
many :: FreshIdT i m a -> FreshIdT i m [a]
$cmany :: forall i (m :: * -> *) a.
Alternative m =>
FreshIdT i m a -> FreshIdT i m [a]
some :: FreshIdT i m a -> FreshIdT i m [a]
$csome :: forall i (m :: * -> *) a.
Alternative m =>
FreshIdT i m a -> FreshIdT i m [a]
<|> :: FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
$c<|> :: forall i (m :: * -> *) a.
Alternative m =>
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
empty :: FreshIdT i m a
$cempty :: forall i (m :: * -> *) a. Alternative m => FreshIdT i m a
$cp1Alternative :: forall i (m :: * -> *). Alternative m => Applicative (FreshIdT i m)
Alternative
    , Applicative (FreshIdT i m)
a -> FreshIdT i m a
Applicative (FreshIdT i m) =>
(forall a b.
 FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b)
-> (forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b)
-> (forall a. a -> FreshIdT i m a)
-> Monad (FreshIdT i m)
FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
forall a. a -> FreshIdT i m a
forall a b. FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
forall a b.
FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b
forall i (m :: * -> *). Monad m => Applicative (FreshIdT i m)
forall i (m :: * -> *) a. Monad m => a -> FreshIdT i m a
forall i (m :: * -> *) a b.
Monad m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
forall i (m :: * -> *) a b.
Monad m =>
FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> FreshIdT i m a
$creturn :: forall i (m :: * -> *) a. Monad m => a -> FreshIdT i m a
>> :: FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
$c>> :: forall i (m :: * -> *) a b.
Monad m =>
FreshIdT i m a -> FreshIdT i m b -> FreshIdT i m b
>>= :: FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b
$c>>= :: forall i (m :: * -> *) a b.
Monad m =>
FreshIdT i m a -> (a -> FreshIdT i m b) -> FreshIdT i m b
$cp1Monad :: forall i (m :: * -> *). Monad m => Applicative (FreshIdT i m)
Monad
    , Monad (FreshIdT i m)
Monad (FreshIdT i m) =>
(forall a. String -> FreshIdT i m a) -> MonadFail (FreshIdT i m)
String -> FreshIdT i m a
forall a. String -> FreshIdT i m a
forall i (m :: * -> *). MonadFail m => Monad (FreshIdT i m)
forall i (m :: * -> *) a. MonadFail m => String -> FreshIdT i m a
forall (m :: * -> *).
Monad m =>
(forall a. String -> m a) -> MonadFail m
fail :: String -> FreshIdT i m a
$cfail :: forall i (m :: * -> *) a. MonadFail m => String -> FreshIdT i m a
$cp1MonadFail :: forall i (m :: * -> *). MonadFail m => Monad (FreshIdT i m)
MonadFail
    , Monad (FreshIdT i m)
Alternative (FreshIdT i m)
FreshIdT i m a
(Alternative (FreshIdT i m), Monad (FreshIdT i m)) =>
(forall a. FreshIdT i m a)
-> (forall a. FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a)
-> MonadPlus (FreshIdT i m)
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
forall a. FreshIdT i m a
forall a. FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
forall i (m :: * -> *). MonadPlus m => Monad (FreshIdT i m)
forall i (m :: * -> *). MonadPlus m => Alternative (FreshIdT i m)
forall i (m :: * -> *) a. MonadPlus m => FreshIdT i m a
forall i (m :: * -> *) a.
MonadPlus m =>
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
forall (m :: * -> *).
(Alternative m, Monad m) =>
(forall a. m a) -> (forall a. m a -> m a -> m a) -> MonadPlus m
mplus :: FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
$cmplus :: forall i (m :: * -> *) a.
MonadPlus m =>
FreshIdT i m a -> FreshIdT i m a -> FreshIdT i m a
mzero :: FreshIdT i m a
$cmzero :: forall i (m :: * -> *) a. MonadPlus m => FreshIdT i m a
$cp2MonadPlus :: forall i (m :: * -> *). MonadPlus m => Monad (FreshIdT i m)
$cp1MonadPlus :: forall i (m :: * -> *). MonadPlus m => Alternative (FreshIdT i m)
MonadPlus
    , Monad (FreshIdT i m)
Monad (FreshIdT i m) =>
(forall a. (a -> FreshIdT i m a) -> FreshIdT i m a)
-> MonadFix (FreshIdT i m)
(a -> FreshIdT i m a) -> FreshIdT i m a
forall a. (a -> FreshIdT i m a) -> FreshIdT i m a
forall i (m :: * -> *). MonadFix m => Monad (FreshIdT i m)
forall i (m :: * -> *) a.
MonadFix m =>
(a -> FreshIdT i m a) -> FreshIdT i m a
forall (m :: * -> *).
Monad m =>
(forall a. (a -> m a) -> m a) -> MonadFix m
mfix :: (a -> FreshIdT i m a) -> FreshIdT i m a
$cmfix :: forall i (m :: * -> *) a.
MonadFix m =>
(a -> FreshIdT i m a) -> FreshIdT i m a
$cp1MonadFix :: forall i (m :: * -> *). MonadFix m => Monad (FreshIdT i m)
MonadFix
    , Monad (FreshIdT i m)
a -> FreshIdT i m (Ref (FreshIdT i m) a)
Monad (FreshIdT i m) =>
(forall a. a -> FreshIdT i m (Ref (FreshIdT i m) a))
-> (forall a. Ref (FreshIdT i m) a -> FreshIdT i m a)
-> (forall a. Ref (FreshIdT i m) a -> a -> FreshIdT i m ())
-> (forall a. Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ())
-> (forall a. Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ())
-> MonadRef (FreshIdT i m)
Ref (FreshIdT i m) a -> FreshIdT i m a
Ref (FreshIdT i m) a -> a -> FreshIdT i m ()
Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
forall a. a -> FreshIdT i m (Ref (FreshIdT i m) a)
forall a. Ref (FreshIdT i m) a -> FreshIdT i m a
forall a. Ref (FreshIdT i m) a -> a -> FreshIdT i m ()
forall a. Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
forall i (m :: * -> *). MonadRef m => Monad (FreshIdT i m)
forall i (m :: * -> *) a.
MonadRef m =>
a -> FreshIdT i m (Ref (FreshIdT i m) a)
forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> FreshIdT i m a
forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> a -> FreshIdT i m ()
forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
forall (m :: * -> *).
Monad m =>
(forall a. a -> m (Ref m a))
-> (forall a. Ref m a -> m a)
-> (forall a. Ref m a -> a -> m ())
-> (forall a. Ref m a -> (a -> a) -> m ())
-> (forall a. Ref m a -> (a -> a) -> m ())
-> MonadRef m
modifyRef' :: Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
$cmodifyRef' :: forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
modifyRef :: Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
$cmodifyRef :: forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> (a -> a) -> FreshIdT i m ()
writeRef :: Ref (FreshIdT i m) a -> a -> FreshIdT i m ()
$cwriteRef :: forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> a -> FreshIdT i m ()
readRef :: Ref (FreshIdT i m) a -> FreshIdT i m a
$creadRef :: forall i (m :: * -> *) a.
MonadRef m =>
Ref (FreshIdT i m) a -> FreshIdT i m a
newRef :: a -> FreshIdT i m (Ref (FreshIdT i m) a)
$cnewRef :: forall i (m :: * -> *) a.
MonadRef m =>
a -> FreshIdT i m (Ref (FreshIdT i m) a)
$cp1MonadRef :: forall i (m :: * -> *). MonadRef m => Monad (FreshIdT i m)
MonadRef
    , MonadRef (FreshIdT i m)
Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
MonadRef (FreshIdT i m) =>
(forall a b.
 Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b)
-> (forall a b.
    Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b)
-> MonadAtomicRef (FreshIdT i m)
forall a b. Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
forall i (m :: * -> *). MonadAtomicRef m => MonadRef (FreshIdT i m)
forall i (m :: * -> *) a b.
MonadAtomicRef m =>
Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
forall (m :: * -> *).
MonadRef m =>
(forall a b. Ref m a -> (a -> (a, b)) -> m b)
-> (forall a b. Ref m a -> (a -> (a, b)) -> m b)
-> MonadAtomicRef m
atomicModifyRef' :: Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
$catomicModifyRef' :: forall i (m :: * -> *) a b.
MonadAtomicRef m =>
Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
atomicModifyRef :: Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
$catomicModifyRef :: forall i (m :: * -> *) a b.
MonadAtomicRef m =>
Ref (FreshIdT i m) a -> (a -> (a, b)) -> FreshIdT i m b
$cp1MonadAtomicRef :: forall i (m :: * -> *). MonadAtomicRef m => MonadRef (FreshIdT i m)
MonadAtomicRef
    , Monad (FreshIdT i m)
Monad (FreshIdT i m) =>
(forall a. IO a -> FreshIdT i m a) -> MonadIO (FreshIdT i m)
IO a -> FreshIdT i m a
forall a. IO a -> FreshIdT i m a
forall i (m :: * -> *). MonadIO m => Monad (FreshIdT i m)
forall i (m :: * -> *) a. MonadIO m => IO a -> FreshIdT i m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> FreshIdT i m a
$cliftIO :: forall i (m :: * -> *) a. MonadIO m => IO a -> FreshIdT i m a
$cp1MonadIO :: forall i (m :: * -> *). MonadIO m => Monad (FreshIdT i m)
MonadIO
    , MonadThrow (FreshIdT i m)
MonadThrow (FreshIdT i m) =>
(forall e a.
 Exception e =>
 FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a)
-> MonadCatch (FreshIdT i m)
FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a
forall e a.
Exception e =>
FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a
forall i (m :: * -> *). MonadCatch m => MonadThrow (FreshIdT i m)
forall i (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a
forall (m :: * -> *).
MonadThrow m =>
(forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
catch :: FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a
$ccatch :: forall i (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
FreshIdT i m a -> (e -> FreshIdT i m a) -> FreshIdT i m a
$cp1MonadCatch :: forall i (m :: * -> *). MonadCatch m => MonadThrow (FreshIdT i m)
MonadCatch
    , Monad (FreshIdT i m)
e -> FreshIdT i m a
Monad (FreshIdT i m) =>
(forall e a. Exception e => e -> FreshIdT i m a)
-> MonadThrow (FreshIdT i m)
forall e a. Exception e => e -> FreshIdT i m a
forall i (m :: * -> *). MonadThrow m => Monad (FreshIdT i m)
forall i (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> FreshIdT i m a
forall (m :: * -> *).
Monad m =>
(forall e a. Exception e => e -> m a) -> MonadThrow m
throwM :: e -> FreshIdT i m a
$cthrowM :: forall i (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> FreshIdT i m a
$cp1MonadThrow :: forall i (m :: * -> *). MonadThrow m => Monad (FreshIdT i m)
MonadThrow
    , MonadCatch (FreshIdT i m)
MonadCatch (FreshIdT i m) =>
(forall b.
 ((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
 -> FreshIdT i m b)
-> (forall b.
    ((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
    -> FreshIdT i m b)
-> (forall a b c.
    FreshIdT i m a
    -> (a -> ExitCase b -> FreshIdT i m c)
    -> (a -> FreshIdT i m b)
    -> FreshIdT i m (b, c))
-> MonadMask (FreshIdT i m)
FreshIdT i m a
-> (a -> ExitCase b -> FreshIdT i m c)
-> (a -> FreshIdT i m b)
-> FreshIdT i m (b, c)
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
forall b.
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
forall a b c.
FreshIdT i m a
-> (a -> ExitCase b -> FreshIdT i m c)
-> (a -> FreshIdT i m b)
-> FreshIdT i m (b, c)
forall i (m :: * -> *). MonadMask m => MonadCatch (FreshIdT i m)
forall i (m :: * -> *) b.
MonadMask m =>
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
forall i (m :: * -> *) a b c.
MonadMask m =>
FreshIdT i m a
-> (a -> ExitCase b -> FreshIdT i m c)
-> (a -> FreshIdT i m b)
-> FreshIdT i m (b, c)
forall (m :: * -> *).
MonadCatch m =>
(forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
generalBracket :: FreshIdT i m a
-> (a -> ExitCase b -> FreshIdT i m c)
-> (a -> FreshIdT i m b)
-> FreshIdT i m (b, c)
$cgeneralBracket :: forall i (m :: * -> *) a b c.
MonadMask m =>
FreshIdT i m a
-> (a -> ExitCase b -> FreshIdT i m c)
-> (a -> FreshIdT i m b)
-> FreshIdT i m (b, c)
uninterruptibleMask :: ((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
$cuninterruptibleMask :: forall i (m :: * -> *) b.
MonadMask m =>
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
mask :: ((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
$cmask :: forall i (m :: * -> *) b.
MonadMask m =>
((forall a. FreshIdT i m a -> FreshIdT i m a) -> FreshIdT i m b)
-> FreshIdT i m b
$cp1MonadMask :: forall i (m :: * -> *). MonadMask m => MonadCatch (FreshIdT i m)
MonadMask
    )

instance MonadTrans (FreshIdT i) where
  lift :: m a -> FreshIdT i m a
lift = ReaderT (Var m i) m a -> FreshIdT i m a
forall i (m :: * -> *) a. ReaderT (Var m i) m a -> FreshIdT i m a
FreshIdT (ReaderT (Var m i) m a -> FreshIdT i m a)
-> (m a -> ReaderT (Var m i) m a) -> m a -> FreshIdT i m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (Var m i) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance MonadBase b m => MonadBase b (FreshIdT i m) where
  liftBase :: b α -> FreshIdT i m α
liftBase = ReaderT (Var m i) m α -> FreshIdT i m α
forall i (m :: * -> *) a. ReaderT (Var m i) m a -> FreshIdT i m a
FreshIdT (ReaderT (Var m i) m α -> FreshIdT i m α)
-> (b α -> ReaderT (Var m i) m α) -> b α -> FreshIdT i m α
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b α -> ReaderT (Var m i) m α
forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
liftBase

instance ( MonadVar m
         , Eq i
         , Ord i
         , Show i
         , Enum i
         , Typeable i
         )
         => MonadThunkId (FreshIdT i m) where
  type ThunkId (FreshIdT i m) = i
  freshId :: FreshIdT i m (ThunkId (FreshIdT i m))
freshId = ReaderT (Var m i) m i -> FreshIdT i m (ThunkId (FreshIdT i m))
forall i (m :: * -> *) a. ReaderT (Var m i) m a -> FreshIdT i m a
FreshIdT (ReaderT (Var m i) m i -> FreshIdT i m (ThunkId (FreshIdT i m)))
-> ReaderT (Var m i) m i -> FreshIdT i m (ThunkId (FreshIdT i m))
forall a b. (a -> b) -> a -> b
$ do
    Var m i
v <- ReaderT (Var m i) m (Var m i)
forall r (m :: * -> *). MonadReader r m => m r
ask
    Ref (ReaderT (Var m i) m) i
-> (i -> (i, i)) -> ReaderT (Var m i) m i
forall (m :: * -> *) a b.
MonadAtomicRef m =>
Ref m a -> (a -> (a, b)) -> m b
atomicModifyVar Var m i
Ref (ReaderT (Var m i) m) i
v (\i :: i
i -> (i -> i
forall a. Enum a => a -> a
succ i
i, i
i))

runFreshIdT :: Functor m => Var m i -> FreshIdT i m a -> m a
runFreshIdT :: Var m i -> FreshIdT i m a -> m a
runFreshIdT i :: Var m i
i m :: FreshIdT i m a
m = ReaderT (Var m i) m a -> Var m i -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (FreshIdT i m a -> ReaderT (Var m i) m a
forall i (m :: * -> *) a. FreshIdT i m a -> ReaderT (Var m i) m a
unFreshIdT FreshIdT i m a
m) Var m i
i

-- Orphan instance needed by Infer.hs and Lint.hs

-- Since there's no forking, it's automatically atomic.
instance MonadAtomicRef (ST s) where
  atomicModifyRef :: Ref (ST s) a -> (a -> (a, b)) -> ST s b
atomicModifyRef r :: Ref (ST s) a
r f :: a -> (a, b)
f = do
    a
v <- Ref (ST s) a -> ST s a
forall (m :: * -> *) a. MonadRef m => Ref m a -> m a
readRef Ref (ST s) a
r
    let (a :: a
a, b :: b
b) = a -> (a, b)
f a
v
    Ref (ST s) a -> a -> ST s ()
forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> m ()
writeRef Ref (ST s) a
r a
a
    b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b
  atomicModifyRef' :: Ref (ST s) a -> (a -> (a, b)) -> ST s b
atomicModifyRef' r :: Ref (ST s) a
r f :: a -> (a, b)
f = do
    a
v <- Ref (ST s) a -> ST s a
forall (m :: * -> *) a. MonadRef m => Ref m a -> m a
readRef Ref (ST s) a
r
    let (a :: a
a, b :: b
b) = a -> (a, b)
f a
v
    Ref (ST s) a -> a -> ST s ()
forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> m ()
writeRef Ref (ST s) a
r (a -> ST s ()) -> a -> ST s ()
forall a b. (a -> b) -> a -> b
$! a
a
    b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b