rename Poly -> Semantic

This commit is contained in:
Sandy Maguire 2019-03-20 00:28:01 -04:00
parent 5d7d957b9a
commit 0684ea3dc6
6 changed files with 86 additions and 77 deletions

View File

@ -32,148 +32,151 @@ import Polysemy.Lift
import Polysemy.Union import Polysemy.Union
newtype Poly r a = Poly newtype Semantic r a = Semantic
{ runPoly { runSemantic
:: m :: m
. Monad m . Monad m
=> ( x. Union r (Poly r) x -> m x) => ( x. Union r (Semantic r) x -> m x)
-> m a -> m a
} }
usingPoly :: Monad m => ( x. Union r (Poly r) x -> m x) -> Poly r a -> m a usingSemantic :: Monad m => ( x. Union r (Semantic r) x -> m x) -> Semantic r a -> m a
usingPoly k m = runPoly m k usingSemantic k m = runSemantic m k
{-# INLINE usingPoly #-} {-# INLINE usingSemantic #-}
instance Functor (Poly f) where instance Functor (Semantic f) where
fmap f (Poly m) = Poly $ \k -> fmap f $ m k fmap f (Semantic m) = Semantic $ \k -> fmap f $ m k
{-# INLINE fmap #-} {-# INLINE fmap #-}
instance Applicative (Poly f) where instance Applicative (Semantic f) where
pure a = Poly $ const $ pure a pure a = Semantic $ const $ pure a
{-# INLINE pure #-} {-# INLINE pure #-}
Poly f <*> Poly a = Poly $ \k -> f k <*> a k Semantic f <*> Semantic a = Semantic $ \k -> f k <*> a k
{-# INLINE (<*>) #-} {-# INLINE (<*>) #-}
instance Monad (Poly f) where instance Monad (Semantic f) where
return = pure return = pure
{-# INLINE return #-} {-# INLINE return #-}
Poly ma >>= f = Poly $ \k -> do Semantic ma >>= f = Semantic $ \k -> do
z <- ma k z <- ma k
runPoly (f z) k runSemantic (f z) k
{-# INLINE (>>=) #-} {-# INLINE (>>=) #-}
instance (Member (Lift IO) r) => MonadIO (Poly r) where instance (Member (Lift IO) r) => MonadIO (Semantic r) where
liftIO = sendM liftIO = sendM
{-# INLINE liftIO #-} {-# INLINE liftIO #-}
instance MonadFix (Poly '[]) where instance MonadFix (Semantic '[]) where
mfix f = a mfix f = a
where where
a = f (run a) a = f (run a)
liftPoly :: Union r (Poly r) a -> Poly r a liftSemantic :: Union r (Semantic r) a -> Semantic r a
liftPoly u = Poly $ \k -> k u liftSemantic u = Semantic $ \k -> k u
{-# INLINE liftPoly #-} {-# INLINE liftSemantic #-}
hoistPoly :: ( x. Union r (Poly r) x -> Union r' (Poly r') x) -> Poly r a -> Poly r' a hoistSemantic
hoistPoly nat (Poly m) = Poly $ \k -> m $ \u -> k $ nat u :: ( x. Union r (Semantic r) x -> Union r' (Semantic r') x)
{-# INLINE hoistPoly #-} -> Semantic r a
-> Semantic r' a
hoistSemantic nat (Semantic m) = Semantic $ \k -> m $ \u -> k $ nat u
{-# INLINE hoistSemantic #-}
send :: Member e r => e (Poly r) a -> Poly r a send :: Member e r => e (Semantic r) a -> Semantic r a
send = liftPoly . inj send = liftSemantic . inj
{-# INLINE[3] send #-} {-# INLINE[3] send #-}
sendM :: Member (Lift m) r => m a -> Poly r a sendM :: Member (Lift m) r => m a -> Semantic r a
sendM = send . Lift sendM = send . Lift
{-# INLINE sendM #-} {-# INLINE sendM #-}
run :: Poly '[] a -> a run :: Semantic '[] a -> a
run (Poly m) = runIdentity $ m absurdU run (Semantic m) = runIdentity $ m absurdU
{-# INLINE run #-} {-# INLINE run #-}
runM :: Monad m => Poly '[Lift m] a -> m a runM :: Monad m => Semantic '[Lift m] a -> m a
runM (Poly m) = m $ unLift . extract runM (Semantic m) = m $ unLift . extract
{-# INLINE runM #-} {-# INLINE runM #-}
interpret interpret
:: Effect e :: Effect e
=> ( x. e (Poly (e ': r)) x -> Poly r x) => ( x. e (Semantic (e ': r)) x -> Semantic r x)
-> Poly (e ': r) a -> Semantic (e ': r) a
-> Poly r a -> Semantic r a
interpret f (Poly m) = m $ \u -> interpret f (Semantic m) = m $ \u ->
case decomp u of case decomp u of
Left x -> liftPoly $ hoist (interpret f) x Left x -> liftSemantic $ hoist (interpret f) x
Right y -> f y Right y -> f y
{-# INLINE interpret #-} {-# INLINE interpret #-}
stateful stateful
:: Effect e :: Effect e
=> ( x. e (Poly (e ': r)) x -> StateT s (Poly r) x) => ( x. e (Semantic (e ': r)) x -> StateT s (Semantic r) x)
-> s -> s
-> Poly (e ': r) a -> Semantic (e ': r) a
-> Poly r (s, a) -> Semantic r (s, a)
stateful f s (Poly m) = Poly $ \k -> stateful f s (Semantic m) = Semantic $ \k ->
fmap swap $ flip S.runStateT s $ m $ \u -> fmap swap $ flip S.runStateT s $ m $ \u ->
case decomp u of case decomp u of
Left x -> S.StateT $ \s' -> Left x -> S.StateT $ \s' ->
k . fmap swap k . fmap swap
. weave (s', ()) (uncurry $ stateful' f) . weave (s', ()) (uncurry $ stateful' f)
$ x $ x
Right y -> S.mapStateT (usingPoly k) $ f y Right y -> S.mapStateT (usingSemantic k) $ f y
{-# INLINE stateful #-} {-# INLINE stateful #-}
stateful' stateful'
:: Effect e :: Effect e
=> ( x. e (Poly (e ': r)) x -> StateT s (Poly r) x) => ( x. e (Semantic (e ': r)) x -> StateT s (Semantic r) x)
-> s -> s
-> Poly (e ': r) a -> Semantic (e ': r) a
-> Poly r (s, a) -> Semantic r (s, a)
stateful' = stateful stateful' = stateful
{-# NOINLINE stateful' #-} {-# NOINLINE stateful' #-}
reinterpret reinterpret
:: Effect f :: Effect f
=> ( x. f (Poly (f ': r)) x -> Poly (g ': r) x) => ( x. f (Semantic (f ': r)) x -> Semantic (g ': r) x)
-> Poly (f ': r) a -> Semantic (f ': r) a
-> Poly (g ': r) a -> Semantic (g ': r) a
reinterpret f (Poly m) = Poly $ \k -> m $ \u -> reinterpret f (Semantic m) = Semantic $ \k -> m $ \u ->
case prjCoerce u of case prjCoerce u of
Left x -> k $ hoist (reinterpret' f) $ x Left x -> k $ hoist (reinterpret' f) $ x
Right y -> usingPoly k $ f y Right y -> usingSemantic k $ f y
{-# INLINE[3] reinterpret #-} {-# INLINE[3] reinterpret #-}
reinterpret' reinterpret'
:: Effect f :: Effect f
=> ( x. f (Poly (f ': r)) x -> Poly (g ': r) x) => ( x. f (Semantic (f ': r)) x -> Semantic (g ': r) x)
-> Poly (f ': r) a -> Semantic (f ': r) a
-> Poly (g ': r) a -> Semantic (g ': r) a
reinterpret' = reinterpret reinterpret' = reinterpret
{-# NOINLINE reinterpret' #-} {-# NOINLINE reinterpret' #-}
runRelayS runRelayS
:: Effect e :: Effect e
=> ( x. e (Poly (e ': r)) x -> s -> Poly r (s, x)) => ( x. e (Semantic (e ': r)) x -> s -> Semantic r (s, x))
-> s -> s
-> Poly (e ': r) a -> Semantic (e ': r) a
-> Poly r (s, a) -> Semantic r (s, a)
runRelayS f = stateful $ \e -> S.StateT $ fmap swap . f e runRelayS f = stateful $ \e -> S.StateT $ fmap swap . f e
{-# INLINE runRelayS #-} {-# INLINE runRelayS #-}

View File

@ -38,22 +38,26 @@ instance Effect (Error e) where
{-# INLINE hoist #-} {-# INLINE hoist #-}
throw :: Member (Error e) r => e -> Poly r a throw :: Member (Error e) r => e -> Semantic r a
throw = send . Throw throw = send . Throw
catch :: Member (Error e) r => Poly r a -> (e -> Poly r a) -> Poly r a catch
:: Member (Error e) r
=> Semantic r a
-> (e -> Semantic r a)
-> Semantic r a
catch try handle = send $ Catch try handle id catch try handle = send $ Catch try handle id
runError :: Poly (Error e ': r) a -> Poly r (Either e a) runError :: Semantic (Error e ': r) a -> Semantic r (Either e a)
runError (Poly m) = Poly $ \k -> E.runExceptT $ m $ \u -> runError (Semantic m) = Semantic $ \k -> E.runExceptT $ m $ \u ->
case decomp u of case decomp u of
Left x -> E.ExceptT $ k $ Left x -> E.ExceptT $ k $
weave (Right ()) (either (pure . Left) runError') x weave (Right ()) (either (pure . Left) runError') x
Right (Throw e) -> E.throwE e Right (Throw e) -> E.throwE e
Right (Catch try handle kt) -> E.ExceptT $ do Right (Catch try handle kt) -> E.ExceptT $ do
let runIt = usingPoly k . runError' let runIt = usingSemantic k . runError'
ma <- runIt try ma <- runIt try
case ma of case ma of
Right a -> pure . Right $ kt a Right a -> pure . Right $ kt a
@ -65,7 +69,7 @@ runError (Poly m) = Poly $ \k -> E.runExceptT $ m $ \u ->
{-# INLINE runError #-} {-# INLINE runError #-}
runError' :: Poly (Error e ': r) a -> Poly r (Either e a) runError' :: Semantic (Error e ': r) a -> Semantic r (Either e a)
runError' = runError runError' = runError
{-# NOINLINE runError' #-} {-# NOINLINE runError' #-}

View File

@ -43,10 +43,10 @@ instance Effect Resource where
bracket bracket
:: Member Resource r :: Member Resource r
=> Poly r a => Semantic r a
-> (a -> Poly r ()) -> (a -> Semantic r ())
-> (a -> Poly r b) -> (a -> Semantic r b)
-> Poly r b -> Semantic r b
bracket alloc dealloc use = send $ Bracket alloc dealloc use id bracket alloc dealloc use = send $ Bracket alloc dealloc use id
{-# INLINE bracket #-} {-# INLINE bracket #-}
@ -54,12 +54,12 @@ bracket alloc dealloc use = send $ Bracket alloc dealloc use id
runResource runResource
:: forall r a :: forall r a
. Member (Lift IO) r . Member (Lift IO) r
=> ( x. Poly r x -> IO x) => ( x. Semantic r x -> IO x)
-> Poly (Resource ': r) a -> Semantic (Resource ': r) a
-> Poly r a -> Semantic r a
runResource finish = interpret $ \case runResource finish = interpret $ \case
Bracket alloc dealloc use k -> fmap k . sendM $ Bracket alloc dealloc use k -> fmap k . sendM $
let runIt :: Poly (Resource ': r) x -> IO x let runIt :: Semantic (Resource ': r) x -> IO x
runIt = finish . runResource' finish runIt = finish . runResource' finish
in X.bracket in X.bracket
(runIt alloc) (runIt alloc)
@ -70,9 +70,9 @@ runResource finish = interpret $ \case
runResource' runResource'
:: Member (Lift IO) r :: Member (Lift IO) r
=> ( x. Poly r x -> IO x) => ( x. Semantic r x -> IO x)
-> Poly (Resource ': r) a -> Semantic (Resource ': r) a
-> Poly r a -> Semantic r a
runResource' = runResource runResource' = runResource
{-# NOINLINE runResource' #-} {-# NOINLINE runResource' #-}

View File

@ -5,6 +5,7 @@
{-# LANGUAGE GADTs #-} {-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-} {-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
module Polysemy.State module Polysemy.State
@ -18,6 +19,7 @@ module Polysemy.State
import qualified Control.Monad.Trans.State.Strict as S import qualified Control.Monad.Trans.State.Strict as S
import Polysemy import Polysemy
import Polysemy.Effect import Polysemy.Effect
import Polysemy.Effect.TH
data State s m a data State s m a
@ -26,31 +28,31 @@ data State s m a
deriving (Functor, Effect) deriving (Functor, Effect)
get :: Member (State s) r => Poly r s get :: Member (State s) r => Semantic r s
get = send $ Get id get = send $ Get id
{-# INLINE get #-} {-# INLINE get #-}
put :: Member (State s) r => s -> Poly r () put :: Member (State s) r => s -> Semantic r ()
put s = send $ Put s () put s = send $ Put s ()
{-# INLINE put #-} {-# INLINE put #-}
modify :: Member (State s) r => (s -> s) -> Poly r () modify :: Member (State s) r => (s -> s) -> Semantic r ()
modify f = do modify f = do
s <- get s <- get
put $ f s put $ f s
{-# INLINE modify #-} {-# INLINE modify #-}
runState :: s -> Poly (State s ': r) a -> Poly r (s, a) runState :: s -> Semantic (State s ': r) a -> Semantic r (s, a)
runState = stateful $ \case runState = stateful $ \case
Get k -> fmap k S.get Get k -> fmap k S.get
Put s k -> S.put s >> pure k Put s k -> S.put s >> pure k
{-# INLINE[3] runState #-} {-# INLINE[3] runState #-}
{-# RULES "runState/reinterpret" {-# RULES "runState/reinterpret"
forall s e (f :: forall x. e (Poly (e ': r)) x -> Poly (State s ': r) x). forall s e (f :: forall x. e (Semantic (e ': r)) x -> Semantic (State s ': r) x).
runState s (reinterpret f e) = runRelayS (\x s' -> runState s' $ f x) s e runState s (reinterpret f e) = runRelayS (\x s' -> runState s' $ f x) s e
#-} #-}

View File

@ -8,7 +8,7 @@ module Wtf where
import Polysemy import Polysemy
import Polysemy.State import Polysemy.State
go :: Member (State Int) r => Poly r Int go :: Member (State Int) r => Semantic r Int
go = do go = do
n <- get n <- get
if n <= 0 if n <= 0

View File

@ -42,7 +42,7 @@ spec = do
shouldSucceed $(inspectTest $ 'jank `doesNotUse` 'hoist) shouldSucceed $(inspectTest $ 'jank `doesNotUse` 'hoist)
go :: Poly '[State Int] Int go :: Semantic '[State Int] Int
go = do go = do
n <- send (Get id) n <- send (Get id)
if n <= 0 if n <= 0