{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
module Symantic.SharingObserver where
import Control.Applicative (Applicative(..))
import Control.Monad (Monad(..))
import Data.Bool
import Data.Eq (Eq(..))
import Data.Function (($), (.))
import Data.Functor (Functor, (<$>))
import Data.Functor.Compose (Compose(..))
import Data.HashMap.Strict (HashMap)
import Data.HashSet (HashSet)
import Data.Hashable (Hashable, hashWithSalt, hash)
import Data.Int (Int)
import Data.Maybe (Maybe(..), isNothing)
import Data.Monoid (Monoid(..))
import Data.Ord (Ord(..))
import GHC.StableName (StableName(..), makeStableName, hashStableName, eqStableName)
import Prelude ((+), error)
import System.IO (IO)
import System.IO.Unsafe (unsafePerformIO)
import Text.Show (Show(..))
import qualified Control.Monad.Trans.Class as MT
import qualified Control.Monad.Trans.Reader as MT
import qualified Control.Monad.Trans.State as MT
import qualified Control.Monad.Trans.Writer as MT
import qualified Data.HashMap.Strict as HM
import qualified Data.HashSet as HS
import Symantic.Derive
class Referenceable letName repr where
ref :: Bool -> letName -> repr a
ref Bool
isRec letName
name = Derived repr a -> repr a
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (Bool -> letName -> Derived repr a
forall letName (repr :: * -> *) a.
Referenceable letName repr =>
Bool -> letName -> repr a
ref Bool
isRec letName
name)
default ref ::
FromDerived (Referenceable letName) repr =>
Bool -> letName -> repr a
class Definable letName repr where
define :: letName -> repr a -> repr a
define letName
name = (Derived repr a -> Derived repr a) -> repr a -> repr a
forall (repr :: * -> *) a b.
LiftDerived1 repr =>
(Derived repr a -> Derived repr b) -> repr a -> repr b
liftDerived1 (letName -> Derived repr a -> Derived repr a
forall letName (repr :: * -> *) a.
Definable letName repr =>
letName -> repr a -> repr a
define letName
name)
default define ::
FromDerived1 (Definable letName) repr =>
letName -> repr a -> repr a
class MakeLetName letName where
makeLetName :: SharingName -> IO letName
data SharingName = forall a. SharingName (StableName a)
makeSharingName :: a -> SharingName
makeSharingName :: a -> SharingName
makeSharingName !a
x = StableName a -> SharingName
forall a. StableName a -> SharingName
SharingName (StableName a -> SharingName) -> StableName a -> SharingName
forall a b. (a -> b) -> a -> b
$ IO (StableName a) -> StableName a
forall a. IO a -> a
unsafePerformIO (IO (StableName a) -> StableName a)
-> IO (StableName a) -> StableName a
forall a b. (a -> b) -> a -> b
$ a -> IO (StableName a)
forall a. a -> IO (StableName a)
makeStableName a
x
instance Eq SharingName where
SharingName StableName a
x == :: SharingName -> SharingName -> Bool
== SharingName StableName a
y = StableName a -> StableName a -> Bool
forall a b. StableName a -> StableName b -> Bool
eqStableName StableName a
x StableName a
y
instance Hashable SharingName where
hash :: SharingName -> Int
hash (SharingName StableName a
n) = StableName a -> Int
forall a. StableName a -> Int
hashStableName StableName a
n
hashWithSalt :: Int -> SharingName -> Int
hashWithSalt Int
salt (SharingName StableName a
n) = Int -> StableName a -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt StableName a
n
newtype SharingObserver letName repr a = SharingObserver { SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver ::
MT.ReaderT (HashSet SharingName)
(MT.State (SharingObserverState letName))
(SharingFinalizer letName repr a) }
observeSharing ::
Eq letName =>
Hashable letName =>
Show letName =>
SharingObserver letName repr a ->
WithSharing letName repr a
observeSharing :: SharingObserver letName repr a -> WithSharing letName repr a
observeSharing (SharingObserver ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
m) =
let (SharingFinalizer letName repr a
fs, SharingObserverState letName
st) = ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> HashSet SharingName
-> State
(SharingObserverState letName) (SharingFinalizer letName repr a)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MT.runReaderT ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
m HashSet SharingName
forall a. Monoid a => a
mempty State
(SharingObserverState letName) (SharingFinalizer letName repr a)
-> SharingObserverState letName
-> (SharingFinalizer letName repr a, SharingObserverState letName)
forall s a. State s a -> s -> (a, s)
`MT.runState`
SharingObserverState :: forall letName.
HashMap SharingName (letName, Int)
-> HashSet SharingName -> SharingObserverState letName
SharingObserverState
{ oss_refs :: HashMap SharingName (letName, Int)
oss_refs = HashMap SharingName (letName, Int)
forall k v. HashMap k v
HM.empty
, oss_recs :: HashSet SharingName
oss_recs = HashSet SharingName
forall a. HashSet a
HS.empty
} in
let refs :: HashSet letName
refs = [letName] -> HashSet letName
forall a. (Eq a, Hashable a) => [a] -> HashSet a
HS.fromList
[ letName
letName
| (letName
letName, Int
refCount) <- HashMap SharingName (letName, Int) -> [(letName, Int)]
forall k v. HashMap k v -> [v]
HM.elems (SharingObserverState letName -> HashMap SharingName (letName, Int)
forall letName.
SharingObserverState letName -> HashMap SharingName (letName, Int)
oss_refs SharingObserverState letName
st)
, Int
refCount Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
] in
Writer (LetBindings letName repr) (repr a)
-> WithSharing letName repr a
forall w a. Writer w a -> (a, w)
MT.runWriter (Writer (LetBindings letName repr) (repr a)
-> WithSharing letName repr a)
-> Writer (LetBindings letName repr) (repr a)
-> WithSharing letName repr a
forall a b. (a -> b) -> a -> b
$
(ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> HashSet letName -> Writer (LetBindings letName repr) (repr a)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`MT.runReaderT` HashSet letName
refs) (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> Writer (LetBindings letName repr) (repr a))
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> Writer (LetBindings letName repr) (repr a)
forall a b. (a -> b) -> a -> b
$
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
fs
type WithSharing letName repr a =
(repr a, HM.HashMap letName (SomeLet repr))
data SharingObserverState letName = SharingObserverState
{ SharingObserverState letName -> HashMap SharingName (letName, Int)
oss_refs :: HashMap SharingName (letName, Int)
, SharingObserverState letName -> HashSet SharingName
oss_recs :: HashSet SharingName
}
observeSharingNode ::
Eq letName =>
Hashable letName =>
Show letName =>
Referenceable letName repr =>
MakeLetName letName =>
SharingObserver letName repr a ->
SharingObserver letName repr a
observeSharingNode :: SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
m) = ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
forall a b. (a -> b) -> a -> b
$ do
let nodeName :: SharingName
nodeName = ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingName
forall a. a -> SharingName
makeSharingName ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
m
SharingObserverState letName
st <- StateT
(SharingObserverState letName)
Identity
(SharingObserverState letName)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingObserverState letName)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
MT.lift StateT
(SharingObserverState letName)
Identity
(SharingObserverState letName)
forall (m :: * -> *) s. Monad m => StateT s m s
MT.get
((letName
letName, Maybe (letName, Int)
seenBefore), HashMap SharingName (letName, Int)
seen) <- Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(HashMap SharingName (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)),
HashMap SharingName (letName, Int))
forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(HashMap SharingName (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)),
HashMap SharingName (letName, Int)))
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(HashMap SharingName (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)),
HashMap SharingName (letName, Int))
forall a b. (a -> b) -> a -> b
$ (Maybe (letName, Int)
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(Maybe (letName, Int)))
-> SharingName
-> HashMap SharingName (letName, Int)
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(HashMap SharingName (letName, Int))
forall (f :: * -> *) k v.
(Functor f, Eq k, Hashable k) =>
(Maybe v -> f (Maybe v)) -> k -> HashMap k v -> f (HashMap k v)
HM.alterF (\Maybe (letName, Int)
seenBefore ->
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(Maybe (letName, Int))
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(Maybe (letName, Int)))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> Compose
(ReaderT
(HashSet SharingName) (State (SharingObserverState letName)))
((,) (letName, Maybe (letName, Int)))
(Maybe (letName, Int))
forall a b. (a -> b) -> a -> b
$ ((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int))
forall (m :: * -> *) a. Monad m => a -> m a
return (((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int)))
-> ((letName, Maybe (letName, Int)), Maybe (letName, Int))
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
((letName, Maybe (letName, Int)), Maybe (letName, Int))
forall a b. (a -> b) -> a -> b
$ case Maybe (letName, Int)
seenBefore of
Maybe (letName, Int)
Nothing ->
((letName
letName, Maybe (letName, Int)
seenBefore), (letName, Int) -> Maybe (letName, Int)
forall a. a -> Maybe a
Just (letName
letName, Int
0))
where letName :: letName
letName = IO letName -> letName
forall a. IO a -> a
unsafePerformIO (IO letName -> letName) -> IO letName -> letName
forall a b. (a -> b) -> a -> b
$ SharingName -> IO letName
forall letName. MakeLetName letName => SharingName -> IO letName
makeLetName SharingName
nodeName
Just (letName
letName, Int
refCount) ->
((letName
letName, Maybe (letName, Int)
seenBefore), (letName, Int) -> Maybe (letName, Int)
forall a. a -> Maybe a
Just (letName
letName, Int
refCount Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
) SharingName
nodeName (SharingObserverState letName -> HashMap SharingName (letName, Int)
forall letName.
SharingObserverState letName -> HashMap SharingName (letName, Int)
oss_refs SharingObserverState letName
st)
HashSet SharingName
parentNames <- ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(HashSet SharingName)
forall (m :: * -> *) r. Monad m => ReaderT r m r
MT.ask
if SharingName
nodeName SharingName -> HashSet SharingName -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`HS.member` HashSet SharingName
parentNames
then do
StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
MT.lift (StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ())
-> StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ()
forall a b. (a -> b) -> a -> b
$ SharingObserverState letName
-> StateT (SharingObserverState letName) Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
MT.put SharingObserverState letName
st
{ oss_refs :: HashMap SharingName (letName, Int)
oss_refs = HashMap SharingName (letName, Int)
seen
, oss_recs :: HashSet SharingName
oss_recs = SharingName -> HashSet SharingName -> HashSet SharingName
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
HS.insert SharingName
nodeName (SharingObserverState letName -> HashSet SharingName
forall letName. SharingObserverState letName -> HashSet SharingName
oss_recs SharingObserverState letName
st)
}
SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a))
-> SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall a b. (a -> b) -> a -> b
$ Bool -> letName -> SharingFinalizer letName repr a
forall letName (repr :: * -> *) a.
Referenceable letName repr =>
Bool -> letName -> repr a
ref Bool
True letName
letName
else do
StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
MT.lift (StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ())
-> StateT (SharingObserverState letName) Identity ()
-> ReaderT
(HashSet SharingName) (State (SharingObserverState letName)) ()
forall a b. (a -> b) -> a -> b
$ SharingObserverState letName
-> StateT (SharingObserverState letName) Identity ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
MT.put SharingObserverState letName
st{ oss_refs :: HashMap SharingName (letName, Int)
oss_refs = HashMap SharingName (letName, Int)
seen }
if Maybe (letName, Int) -> Bool
forall a. Maybe a -> Bool
isNothing Maybe (letName, Int)
seenBefore
then (HashSet SharingName -> HashSet SharingName)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall r (m :: * -> *) a.
(r -> r) -> ReaderT r m a -> ReaderT r m a
MT.local (SharingName -> HashSet SharingName -> HashSet SharingName
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
HS.insert SharingName
nodeName) (letName
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr a
forall letName (repr :: * -> *) a.
Definable letName repr =>
letName -> repr a -> repr a
define letName
letName (SharingFinalizer letName repr a
-> SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
m)
else SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a))
-> SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall a b. (a -> b) -> a -> b
$ Bool -> letName -> SharingFinalizer letName repr a
forall letName (repr :: * -> *) a.
Referenceable letName repr =>
Bool -> letName -> repr a
ref Bool
False letName
letName
type instance Derived (SharingObserver letName repr) = SharingFinalizer letName repr
instance
( Referenceable letName repr
, MakeLetName letName
, Eq letName
, Hashable letName
, Show letName
) => LiftDerived (SharingObserver letName repr) where
liftDerived :: Derived (SharingObserver letName repr) a
-> SharingObserver letName repr a
liftDerived = SharingObserver letName repr a -> SharingObserver letName repr a
forall letName (repr :: * -> *) a.
(Eq letName, Hashable letName, Show letName,
Referenceable letName repr, MakeLetName letName) =>
SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver letName repr a -> SharingObserver letName repr a)
-> (SharingFinalizer letName repr a
-> SharingObserver letName repr a)
-> SharingFinalizer letName repr a
-> SharingObserver letName repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a)
-> (SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a))
-> SharingFinalizer letName repr a
-> SharingObserver letName repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SharingFinalizer letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall (m :: * -> *) a. Monad m => a -> m a
return
instance
( Referenceable letName repr
, MakeLetName letName
, Eq letName
, Hashable letName
, Show letName
) => LiftDerived1 (SharingObserver letName repr) where
liftDerived1 :: (Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b)
-> SharingObserver letName repr a -> SharingObserver letName repr b
liftDerived1 Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
f SharingObserver letName repr a
a = SharingObserver letName repr b -> SharingObserver letName repr b
forall letName (repr :: * -> *) a.
(Eq letName, Hashable letName, Show letName,
Referenceable letName repr, MakeLetName letName) =>
SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver letName repr b -> SharingObserver letName repr b)
-> SharingObserver letName repr b -> SharingObserver letName repr b
forall a b. (a -> b) -> a -> b
$ ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> SharingObserver letName repr b
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> SharingObserver letName repr b)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> SharingObserver letName repr b
forall a b. (a -> b) -> a -> b
$
Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
SharingFinalizer letName repr a -> SharingFinalizer letName repr b
f (SharingFinalizer letName repr a
-> SharingFinalizer letName repr b)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr a
a
instance
( Referenceable letName repr
, MakeLetName letName
, Eq letName
, Hashable letName
, Show letName
) => LiftDerived2 (SharingObserver letName repr) where
liftDerived2 :: (Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c)
-> SharingObserver letName repr a
-> SharingObserver letName repr b
-> SharingObserver letName repr c
liftDerived2 Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
f SharingObserver letName repr a
a SharingObserver letName repr b
b = SharingObserver letName repr c -> SharingObserver letName repr c
forall letName (repr :: * -> *) a.
(Eq letName, Hashable letName, Show letName,
Referenceable letName repr, MakeLetName letName) =>
SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver letName repr c -> SharingObserver letName repr c)
-> SharingObserver letName repr c -> SharingObserver letName repr c
forall a b. (a -> b) -> a -> b
$ ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
-> SharingObserver letName repr c
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
-> SharingObserver letName repr c)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
-> SharingObserver letName repr c
forall a b. (a -> b) -> a -> b
$
Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
f (SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr a
a
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr b
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr b
b
instance
( Referenceable letName repr
, MakeLetName letName
, Eq letName
, Hashable letName
, Show letName
) => LiftDerived3 (SharingObserver letName repr) where
liftDerived3 :: (Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d)
-> SharingObserver letName repr a
-> SharingObserver letName repr b
-> SharingObserver letName repr c
-> SharingObserver letName repr d
liftDerived3 Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d
f SharingObserver letName repr a
a SharingObserver letName repr b
b SharingObserver letName repr c
c = SharingObserver letName repr d -> SharingObserver letName repr d
forall letName (repr :: * -> *) a.
(Eq letName, Hashable letName, Show letName,
Referenceable letName repr, MakeLetName letName) =>
SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver letName repr d -> SharingObserver letName repr d)
-> SharingObserver letName repr d -> SharingObserver letName repr d
forall a b. (a -> b) -> a -> b
$ ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
-> SharingObserver letName repr d
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
-> SharingObserver letName repr d)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
-> SharingObserver letName repr d
forall a b. (a -> b) -> a -> b
$
Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d
SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
f (SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr a
a
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c
-> SharingFinalizer letName repr d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr b
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr b
b
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c
-> SharingFinalizer letName repr d)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr c
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr c
c
instance
( Referenceable letName repr
, MakeLetName letName
, Eq letName
, Hashable letName
, Show letName
) => LiftDerived4 (SharingObserver letName repr) where
liftDerived4 :: (Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d
-> Derived (SharingObserver letName repr) e)
-> SharingObserver letName repr a
-> SharingObserver letName repr b
-> SharingObserver letName repr c
-> SharingObserver letName repr d
-> SharingObserver letName repr e
liftDerived4 Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d
-> Derived (SharingObserver letName repr) e
f SharingObserver letName repr a
a SharingObserver letName repr b
b SharingObserver letName repr c
c SharingObserver letName repr d
d = SharingObserver letName repr e -> SharingObserver letName repr e
forall letName (repr :: * -> *) a.
(Eq letName, Hashable letName, Show letName,
Referenceable letName repr, MakeLetName letName) =>
SharingObserver letName repr a -> SharingObserver letName repr a
observeSharingNode (SharingObserver letName repr e -> SharingObserver letName repr e)
-> SharingObserver letName repr e -> SharingObserver letName repr e
forall a b. (a -> b) -> a -> b
$ ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr e)
-> SharingObserver letName repr e
forall letName (repr :: * -> *) a.
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> SharingObserver letName repr a
SharingObserver (ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr e)
-> SharingObserver letName repr e)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr e)
-> SharingObserver letName repr e
forall a b. (a -> b) -> a -> b
$
Derived (SharingObserver letName repr) a
-> Derived (SharingObserver letName repr) b
-> Derived (SharingObserver letName repr) c
-> Derived (SharingObserver letName repr) d
-> Derived (SharingObserver letName repr) e
SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e
f (SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr a
a
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr b
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr b)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr b
b
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr c
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr c)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr c
c
ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d
-> SharingFinalizer letName repr e)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingObserver letName repr d
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr d)
forall letName (repr :: * -> *) a.
SharingObserver letName repr a
-> ReaderT
(HashSet SharingName)
(State (SharingObserverState letName))
(SharingFinalizer letName repr a)
unSharingObserver SharingObserver letName repr d
d
instance Referenceable letName (SharingObserver letName repr) where
ref :: Bool -> letName -> SharingObserver letName repr a
ref = [Char] -> Bool -> letName -> SharingObserver letName repr a
forall a. HasCallStack => [Char] -> a
error [Char]
"[BUG]: observeSharing MUST NOT be applied twice"
instance Definable letName (SharingObserver letName repr) where
define :: letName
-> SharingObserver letName repr a -> SharingObserver letName repr a
define = [Char]
-> letName
-> SharingObserver letName repr a
-> SharingObserver letName repr a
forall a. HasCallStack => [Char] -> a
error [Char]
"[BUG]: observeSharing MUST NOT be applied twice"
instance Letsable letName (SharingObserver letName repr) where
lets :: LetBindings letName (SharingObserver letName repr)
-> SharingObserver letName repr a -> SharingObserver letName repr a
lets = [Char]
-> LetBindings letName (SharingObserver letName repr)
-> SharingObserver letName repr a
-> SharingObserver letName repr a
forall a. HasCallStack => [Char] -> a
error [Char]
"[BUG]: observeSharing MUST NOT be applied twice"
newtype SharingFinalizer letName repr a = SharingFinalizer { SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing ::
MT.ReaderT (HS.HashSet letName)
(MT.Writer (LetBindings letName repr))
(repr a) }
type instance Derived (SharingFinalizer _letName repr) = repr
instance (Eq letName, Hashable letName) =>
LiftDerived (SharingFinalizer letName repr) where
liftDerived :: Derived (SharingFinalizer letName repr) a
-> SharingFinalizer letName repr a
liftDerived = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a)
-> (repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a))
-> repr a
-> SharingFinalizer letName repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance (Eq letName, Hashable letName) =>
LiftDerived1 (SharingFinalizer letName repr) where
liftDerived1 :: (Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b)
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
liftDerived1 Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
f SharingFinalizer letName repr a
a = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> SharingFinalizer letName repr b
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> SharingFinalizer letName repr b)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> SharingFinalizer letName repr b
forall a b. (a -> b) -> a -> b
$ repr a -> repr b
Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
f (repr a -> repr b)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
a
instance (Eq letName, Hashable letName) =>
LiftDerived2 (SharingFinalizer letName repr) where
liftDerived2 :: (Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c)
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
liftDerived2 Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
f SharingFinalizer letName repr a
a SharingFinalizer letName repr b
b = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
-> SharingFinalizer letName repr c
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
-> SharingFinalizer letName repr c)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
-> SharingFinalizer letName repr c
forall a b. (a -> b) -> a -> b
$
repr a -> repr b -> repr c
Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
f (repr a -> repr b -> repr c)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
a
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr b
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr b
b
instance (Eq letName, Hashable letName) =>
LiftDerived3 (SharingFinalizer letName repr) where
liftDerived3 :: (Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d)
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
liftDerived3 Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d
f SharingFinalizer letName repr a
a SharingFinalizer letName repr b
b SharingFinalizer letName repr c
c = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
-> SharingFinalizer letName repr d
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
-> SharingFinalizer letName repr d)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
-> SharingFinalizer letName repr d
forall a b. (a -> b) -> a -> b
$
repr a -> repr b -> repr c -> repr d
Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d
f (repr a -> repr b -> repr c -> repr d)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c -> repr d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
a
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c -> repr d)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr c -> repr d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr b
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr b
b
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr c -> repr d)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr c
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr c
c
instance (Eq letName, Hashable letName) =>
LiftDerived4 (SharingFinalizer letName repr) where
liftDerived4 :: (Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d
-> Derived (SharingFinalizer letName repr) e)
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr b
-> SharingFinalizer letName repr c
-> SharingFinalizer letName repr d
-> SharingFinalizer letName repr e
liftDerived4 Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d
-> Derived (SharingFinalizer letName repr) e
f SharingFinalizer letName repr a
a SharingFinalizer letName repr b
b SharingFinalizer letName repr c
c SharingFinalizer letName repr d
d = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr e)
-> SharingFinalizer letName repr e
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr e)
-> SharingFinalizer letName repr e)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr e)
-> SharingFinalizer letName repr e
forall a b. (a -> b) -> a -> b
$
repr a -> repr b -> repr c -> repr d -> repr e
Derived (SharingFinalizer letName repr) a
-> Derived (SharingFinalizer letName repr) b
-> Derived (SharingFinalizer letName repr) c
-> Derived (SharingFinalizer letName repr) d
-> Derived (SharingFinalizer letName repr) e
f (repr a -> repr b -> repr c -> repr d -> repr e)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c -> repr d -> repr e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
a
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr b -> repr c -> repr d -> repr e)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr c -> repr d -> repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr b
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr b)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr b
b
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr c -> repr d -> repr e)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
-> ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr d -> repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr c
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr c)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr c
c
ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(repr d -> repr e)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SharingFinalizer letName repr d
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr d)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr d
d
instance
( Referenceable letName repr
, Eq letName
, Hashable letName
, Show letName
) => Referenceable letName (SharingFinalizer letName repr) where
ref :: Bool -> letName -> SharingFinalizer letName repr a
ref Bool
isRec = repr a -> SharingFinalizer letName repr a
forall (repr :: * -> *) a.
LiftDerived repr =>
Derived repr a -> repr a
liftDerived (repr a -> SharingFinalizer letName repr a)
-> (letName -> repr a)
-> letName
-> SharingFinalizer letName repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> letName -> repr a
forall letName (repr :: * -> *) a.
Referenceable letName repr =>
Bool -> letName -> repr a
ref Bool
isRec
instance
( Referenceable letName repr
, Eq letName
, Hashable letName
, Show letName
) => Definable letName (SharingFinalizer letName repr) where
define :: letName
-> SharingFinalizer letName repr a
-> SharingFinalizer letName repr a
define letName
name SharingFinalizer letName repr a
body = ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
forall letName (repr :: * -> *) a.
ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
SharingFinalizer (ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a)
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> SharingFinalizer letName repr a
forall a b. (a -> b) -> a -> b
$ do
HashSet letName
refs <- ReaderT
(HashSet letName)
(Writer (LetBindings letName repr))
(HashSet letName)
forall (m :: * -> *) r. Monad m => ReaderT r m r
MT.ask
let (repr a
repr, LetBindings letName repr
defs) =
Writer (LetBindings letName repr) (repr a)
-> (repr a, LetBindings letName repr)
forall w a. Writer w a -> (a, w)
MT.runWriter (Writer (LetBindings letName repr) (repr a)
-> (repr a, LetBindings letName repr))
-> Writer (LetBindings letName repr) (repr a)
-> (repr a, LetBindings letName repr)
forall a b. (a -> b) -> a -> b
$ ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
-> HashSet letName -> Writer (LetBindings letName repr) (repr a)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
MT.runReaderT (SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
body) HashSet letName
refs
if letName
name letName -> HashSet letName -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`HS.member` HashSet letName
refs
then do
WriterT (LetBindings letName repr) Identity ()
-> ReaderT (HashSet letName) (Writer (LetBindings letName repr)) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
MT.lift (WriterT (LetBindings letName repr) Identity ()
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) ())
-> WriterT (LetBindings letName repr) Identity ()
-> ReaderT (HashSet letName) (Writer (LetBindings letName repr)) ()
forall a b. (a -> b) -> a -> b
$ LetBindings letName repr
-> WriterT (LetBindings letName repr) Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
MT.tell (LetBindings letName repr
-> WriterT (LetBindings letName repr) Identity ())
-> LetBindings letName repr
-> WriterT (LetBindings letName repr) Identity ()
forall a b. (a -> b) -> a -> b
$ letName
-> SomeLet repr
-> LetBindings letName repr
-> LetBindings letName repr
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HM.insert letName
name (repr a -> SomeLet repr
forall (repr :: * -> *) a. repr a -> SomeLet repr
SomeLet repr a
repr) LetBindings letName repr
defs
repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall (m :: * -> *) a. Monad m => a -> m a
return (repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a))
-> repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall a b. (a -> b) -> a -> b
$ Bool -> letName -> repr a
forall letName (repr :: * -> *) a.
Referenceable letName repr =>
Bool -> letName -> repr a
ref Bool
False letName
name
else
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
forall letName (repr :: * -> *) a.
SharingFinalizer letName repr a
-> ReaderT
(HashSet letName) (Writer (LetBindings letName repr)) (repr a)
unFinalizeSharing SharingFinalizer letName repr a
body
class Letsable letName repr where
lets :: LetBindings letName repr -> repr a -> repr a
lets LetBindings letName repr
defs = (Derived repr a -> Derived repr a) -> repr a -> repr a
forall (repr :: * -> *) a b.
LiftDerived1 repr =>
(Derived repr a -> Derived repr b) -> repr a -> repr b
liftDerived1 (LetBindings letName (Derived repr)
-> Derived repr a -> Derived repr a
forall letName (repr :: * -> *) a.
Letsable letName repr =>
LetBindings letName repr -> repr a -> repr a
lets ((\(SomeLet repr a
val) -> Derived repr a -> SomeLet (Derived repr)
forall (repr :: * -> *) a. repr a -> SomeLet repr
SomeLet (repr a -> Derived repr a
forall (repr :: * -> *) a.
Derivable repr =>
repr a -> Derived repr a
derive repr a
val)) (SomeLet repr -> SomeLet (Derived repr))
-> LetBindings letName repr -> LetBindings letName (Derived repr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LetBindings letName repr
defs))
default lets ::
Derivable repr =>
FromDerived1 (Letsable letName) repr =>
LetBindings letName repr -> repr a -> repr a
data SomeLet repr = forall a. SomeLet (repr a)
type LetBindings letName repr = HM.HashMap letName (SomeLet repr)
type OpenRecs letName a = LetRecs letName (OpenRec letName a)
type OpenRec letName a = LetRecs letName a -> a
type LetRecs letName = HM.HashMap letName
fix :: (a -> a) -> a
fix :: (a -> a) -> a
fix a -> a
f = a
final where final :: a
final = a -> a
f a
final
mutualFix :: forall recs a. Functor recs => recs (recs a -> a) -> recs a
mutualFix :: recs (recs a -> a) -> recs a
mutualFix recs (recs a -> a)
opens = (recs a -> recs a) -> recs a
forall a. (a -> a) -> a
fix recs a -> recs a
f
where
f :: recs a -> recs a
f :: recs a -> recs a
f recs a
recs = ((recs a -> a) -> recs a -> a
forall a b. (a -> b) -> a -> b
$ recs a
recs) ((recs a -> a) -> a) -> recs (recs a -> a) -> recs a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> recs (recs a -> a)
opens