duairc / layers Goto Github PK
View Code? Open in Web Editor NEWModular type class machinery for monad transformer stacks.
License: BSD 3-Clause "New" or "Revised" License
Modular type class machinery for monad transformer stacks.
License: BSD 3-Clause "New" or "Revised" License
The following code demonstrates that exiting the body of a bracket produces different results if the exit is due to an exception instead of a monadic guard:
import Control.Monad.Layer
import Control.Monad.Interface.Try
import Control.Monad.Interface.State
import Control.Monad.Trans.State (runStateT)
import Control.Monad.Trans.Maybe (runMaybeT)
import Control.Monad (mzero)
bar :: Bool -> IO (Maybe (), Int)
bar sw = flip runStateT 0 $ runMaybeT $ bracket
(do
lift $ putStrLn "init"
modify (+1))
(\() -> do
modify (+16)
lift $ putStrLn "close"
modify (+32)
mzero
modify (+64))
(\() -> do
modify (+2)
lift $ putStrLn "body"
modify (+4)
if sw then mzero else error "oops"
modify (+8))
main = do
bar True >>= print
bar False >>= print
With this result:
init
body
close
(Nothing,55)
init
body
close
(Nothing,49)
The problem is in the implementation of finally:
finally :: MonadTry m => m a -> m b -> m a
finally m sequel = mask $ \unmask -> do
r <- unmask m `onException` sequel
_ <- sequel
return r
As you can see, the unmasking only completes if no exception is thrown, which means state is only restored in that case. Maybe something like unmask (return ()) >> sequel
is needed here after the onException
?
I'm trying to compile the following code in order to test some of the properties of the layers library:
import Control.Monad.Interface.Cont
import Control.Monad.Interface.Try (bracket_)
import Control.Monad.IO.Class
import Control.Monad.Trans.Cont
f :: ContT (Either String String) IO String
f = do
bracket_ (say "acquired") (say "released") (say "executed")
() <- error "error"
return "success"
where
say = liftIO . putStrLn
main :: IO ()
main = flip runContT (return . Right) f >>= print
But I get this error:
contt.hs:8:5:
No instance for (Control.Monad.Layer.MonadLayerControl
(ContT (Either String String) IO))
arising from a use of `bracket_'
Possible fix:
add an instance declaration for
(Control.Monad.Layer.MonadLayerControl
(ContT (Either String String) IO))
In a stmt of a 'do' block:
bracket_ (say "acquired") (say "released") (say "executed")
In the expression:
do { bracket_ (say "acquired") (say "released") (say "executed");
() <- error "error";
return "success" }
In an equation for `f':
f = do { bracket_
(say "acquired") (say "released") (say "executed");
() <- error "error";
return "success" }
where
say = liftIO . putStrLn
I found this surprising, because I thought one of the virtues of the layers library was that it "solved" the problem of hoisting through ContT?
Hi
Let me preface by saying that this package looks very promising and I am looking forward to experimenting with it. Thanks for putting in that much work! You should try to promote it more. It deserves more exposure. My goal with this package is to reduce the complexity of the bazillion lift
s in my project, which I need to change everytime my transformer stack changes.
I tried installing your package, but it failed with the errors I pasted below. Do you know what is happening here?
Thanks! Marko
[ 1 of 12] Compiling Control.Monad.Layer ( src/Control/Monad/Layer.hs, dist/dist-sandbox-fb504d7f/build/Control/Monad/Layer.o )
src/Control/Monad/Layer.hs:298:19:
Cannot instantiate unification variable ‘a22’
with a type involving foralls:
forall b. Inner (ErrorT e m) b -> Inner (ErrorT e m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (ErrorT e m)’
src/Control/Monad/Layer.hs:298:27:
Cannot instantiate unification variable ‘a22’
with a type involving foralls:
forall b. Inner (ErrorT e m) b -> Inner (ErrorT e m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:322:19:
Cannot instantiate unification variable ‘a21’
with a type involving foralls:
forall b. Inner (ErrorT e m) b -> Inner (ErrorT e (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (ErrorT e m)’
src/Control/Monad/Layer.hs:322:27:
Cannot instantiate unification variable ‘a21’
with a type involving foralls:
forall b. Inner (ErrorT e m) b -> Inner (ErrorT e (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:343:19:
Cannot instantiate unification variable ‘a20’
with a type involving foralls:
forall b. Inner (IdentityT m) b -> Inner (IdentityT m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (IdentityT m)’
src/Control/Monad/Layer.hs:343:27:
Cannot instantiate unification variable ‘a20’
with a type involving foralls:
forall b. Inner (IdentityT m) b -> Inner (IdentityT m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:365:19:
Cannot instantiate unification variable ‘a19’
with a type involving foralls:
forall b. Inner (IdentityT m) b -> Inner (IdentityT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (IdentityT m)’
src/Control/Monad/Layer.hs:365:27:
Cannot instantiate unification variable ‘a19’
with a type involving foralls:
forall b. Inner (IdentityT m) b -> Inner (IdentityT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:386:19:
Cannot instantiate unification variable ‘a18’
with a type involving foralls:
forall b. Inner (ListT m) b -> Inner (ListT m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (ListT m)’
src/Control/Monad/Layer.hs:386:27:
Cannot instantiate unification variable ‘a18’
with a type involving foralls:
forall b. Inner (ListT m) b -> Inner (ListT m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:410:19:
Cannot instantiate unification variable ‘a17’
with a type involving foralls:
forall b. Inner (ListT m) b -> Inner (ListT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (ListT m)’
src/Control/Monad/Layer.hs:410:27:
Cannot instantiate unification variable ‘a17’
with a type involving foralls:
forall b. Inner (ListT m) b -> Inner (ListT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:431:19:
Cannot instantiate unification variable ‘a16’
with a type involving foralls:
forall b. Inner (MaybeT m) b -> Inner (MaybeT m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (MaybeT m)’
src/Control/Monad/Layer.hs:431:27:
Cannot instantiate unification variable ‘a16’
with a type involving foralls:
forall b. Inner (MaybeT m) b -> Inner (MaybeT m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:455:19:
Cannot instantiate unification variable ‘a15’
with a type involving foralls:
forall b. Inner (MaybeT m) b -> Inner (MaybeT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (MaybeT m)’
src/Control/Monad/Layer.hs:455:27:
Cannot instantiate unification variable ‘a15’
with a type involving foralls:
forall b. Inner (MaybeT m) b -> Inner (MaybeT (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:476:19:
Cannot instantiate unification variable ‘a14’
with a type involving foralls:
forall b. Inner (ReaderT r m) b -> Inner (ReaderT r m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (ReaderT r m)’
src/Control/Monad/Layer.hs:476:27:
Cannot instantiate unification variable ‘a14’
with a type involving foralls:
forall b. Inner (ReaderT r m) b -> Inner (ReaderT r m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:498:19:
Cannot instantiate unification variable ‘a13’
with a type involving foralls:
forall b. Inner (ReaderT r m) b -> Inner (ReaderT r (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (ReaderT r m)’
src/Control/Monad/Layer.hs:498:27:
Cannot instantiate unification variable ‘a13’
with a type involving foralls:
forall b. Inner (ReaderT r m) b -> Inner (ReaderT r (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:519:19:
Cannot instantiate unification variable ‘a12’
with a type involving foralls:
forall b. Inner (L.RWST r w s m) b -> Inner (L.RWST r w s m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (L.RWST r w s m)’
src/Control/Monad/Layer.hs:519:27:
Cannot instantiate unification variable ‘a12’
with a type involving foralls:
forall b. Inner (L.RWST r w s m) b -> Inner (L.RWST r w s m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:549:19:
Cannot instantiate unification variable ‘a11’
with a type involving foralls:
forall b.
Inner (L.RWST r w s m) b -> Inner (L.RWST r w s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (L.RWST r w s m)’
src/Control/Monad/Layer.hs:549:27:
Cannot instantiate unification variable ‘a11’
with a type involving foralls:
forall b.
Inner (L.RWST r w s m) b -> Inner (L.RWST r w s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:564:19:
Cannot instantiate unification variable ‘a10’
with a type involving foralls:
forall b. Inner (RWST r w s m) b -> Inner (RWST r w s m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (RWST r w s m)’
src/Control/Monad/Layer.hs:564:27:
Cannot instantiate unification variable ‘a10’
with a type involving foralls:
forall b. Inner (RWST r w s m) b -> Inner (RWST r w s m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:587:19:
Cannot instantiate unification variable ‘a9’
with a type involving foralls:
forall b. Inner (RWST r w s m) b -> Inner (RWST r w s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (RWST r w s m)’
src/Control/Monad/Layer.hs:587:27:
Cannot instantiate unification variable ‘a9’
with a type involving foralls:
forall b. Inner (RWST r w s m) b -> Inner (RWST r w s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:609:19:
Cannot instantiate unification variable ‘a8’
with a type involving foralls:
forall b. Inner (L.StateT s m) b -> Inner (L.StateT s m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (L.StateT s m)’
src/Control/Monad/Layer.hs:609:27:
Cannot instantiate unification variable ‘a8’
with a type involving foralls:
forall b. Inner (L.StateT s m) b -> Inner (L.StateT s m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:632:19:
Cannot instantiate unification variable ‘a7’
with a type involving foralls:
forall b. Inner (L.StateT s m) b -> Inner (L.StateT s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (L.StateT s m)’
src/Control/Monad/Layer.hs:632:27:
Cannot instantiate unification variable ‘a7’
with a type involving foralls:
forall b. Inner (L.StateT s m) b -> Inner (L.StateT s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:654:19:
Cannot instantiate unification variable ‘a6’
with a type involving foralls:
forall b. Inner (StateT s m) b -> Inner (StateT s m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (StateT s m)’
src/Control/Monad/Layer.hs:654:27:
Cannot instantiate unification variable ‘a6’
with a type involving foralls:
forall b. Inner (StateT s m) b -> Inner (StateT s m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:677:19:
Cannot instantiate unification variable ‘a5’
with a type involving foralls:
forall b. Inner (StateT s m) b -> Inner (StateT s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (StateT s m)’
src/Control/Monad/Layer.hs:677:27:
Cannot instantiate unification variable ‘a5’
with a type involving foralls:
forall b. Inner (StateT s m) b -> Inner (StateT s (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:699:19:
Cannot instantiate unification variable ‘a4’
with a type involving foralls:
forall b. Inner (L.WriterT w m) b -> Inner (L.WriterT w m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (L.WriterT w m)’
src/Control/Monad/Layer.hs:699:27:
Cannot instantiate unification variable ‘a4’
with a type involving foralls:
forall b. Inner (L.WriterT w m) b -> Inner (L.WriterT w m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:721:19:
Cannot instantiate unification variable ‘a3’
with a type involving foralls:
forall b.
Inner (L.WriterT w m) b -> Inner (L.WriterT w (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (L.WriterT w m)’
src/Control/Monad/Layer.hs:721:27:
Cannot instantiate unification variable ‘a3’
with a type involving foralls:
forall b.
Inner (L.WriterT w m) b -> Inner (L.WriterT w (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:742:19:
Cannot instantiate unification variable ‘a2’
with a type involving foralls:
forall b. Inner (WriterT w m) b -> Inner (WriterT w m) b
Perhaps you want ImpredicativeTypes
In the expression: const . layerMap
In an equation for ‘layerInvmap’: layerInvmap = const . layerMap
In the instance declaration for ‘MonadLayer (WriterT w m)’
src/Control/Monad/Layer.hs:742:27:
Cannot instantiate unification variable ‘a2’
with a type involving foralls:
forall b. Inner (WriterT w m) b -> Inner (WriterT w m) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘layerMap’
In the expression: const . layerMap
src/Control/Monad/Layer.hs:764:19:
Cannot instantiate unification variable ‘a1’
with a type involving foralls:
forall b. Inner (WriterT w m) b -> Inner (WriterT w (Inner n)) b
Perhaps you want ImpredicativeTypes
In the expression: const . transMap
In an equation for ‘transInvmap’: transInvmap = const . transMap
In the instance declaration for ‘MonadTrans (WriterT w m)’
src/Control/Monad/Layer.hs:764:27:
Cannot instantiate unification variable ‘a1’
with a type involving foralls:
forall b. Inner (WriterT w m) b -> Inner (WriterT w (Inner n)) b
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘transMap’
In the expression: const . transMap
src/Control/Monad/Layer.hs:983:11:
Cannot instantiate unification variable ‘a0’
with a type involving foralls:
(forall b. m b -> i (m b)) -> i (m a)
Perhaps you want ImpredicativeTypes
In the expression: join . liftControl
In an equation for ‘control’: control = join . liftControl
src/Control/Monad/Layer.hs:983:18:
Cannot instantiate unification variable ‘a0’
with a type involving foralls:
(forall b. m b -> i0 (m b)) -> i0 (m a)
Perhaps you want ImpredicativeTypes
In the second argument of ‘(.)’, namely ‘liftControl’
In the expression: join . liftControl
Failed to install layers-0.1
cabal: Error: some packages failed to install:
layers-0.1 failed during the building phase. The exception was:
ExitFailure 1
E.g.:
{-# LANGUAGE DefaultSignatures #-}
class MonadLayer m => MonadLayerFunctor m where
layerMap :: (forall b. Inner m b -> Inner m b) -> m a -> m a
default layerMap :: MonadTransFunctor m => (forall b. Inner m b -> Inner m b) -> m a -> m a
layerMap = transMap
This way having an instance of MonadTransFunctor
, the user will be able to skip the layerMap = transMap
part in the instance declaration of MonadLayerFunctor
.
I liked reading the Overview section, but it doesn't talk about performance. Maybe this is a non-issue for some reason, but mentioning how it actually performs vs other solutions would be good.
http://www.reddit.com/r/haskell/comments/1n7mid/arguing_against_monad_transformers_for_the_right/
I mean, why is its signature LayerState m a -> m a
instead of LayerState m a -> a
? This limits its usability quite a lot.
The documentation complains about how monad-peel/monad-control’s implementation of bracket
discards the monadic effects of the finalizer computation. I’d like to explain why this was intentional, by way of example:
import Control.Monad.Trans
import Control.Monad.Trans.List
-- import Control.Exception.Peel -- monad-peel
-- import Control.Exception.Lifted -- monad-control
import Control.Monad.Interface.Try -- layers
dup :: Int -> ListT IO ()
dup n = ListT (return (take n (repeat ())))
m :: IO [()]
m = runListT $ bracket
(lift (putStrLn "init"))
(\() -> lift (putStrLn "close"))
(\() -> dup 3 >> lift (putStrLn "body"))
monad-peel/monad-control gives the expected result:
λ> m
init
body
body
body
close
[(),(),()]
while layers duplicates the finalizer three times:
λ> m
init
body
body
body
close
close
close
[(),(),()]
In general, when replacing dup 3
by dup n
, monad-peel/monad-control always runs the finalizer exactly once, while layers runs it max {n, 1} times. The latter behavior would be bad for finalizers that expect to be paired one-to-one with initializers (e.g. malloc
/free
).
The zero
logic in MonadLayerControl
looks like it was intended as a hack to deal with short-circuiting monads, but it comes at the expense of mishandling more general kinds of side effects. If you think your short-circuiting behavior is important, zero
should probably be moved into a more specific typeclass that ListT
does not satisfy, or perhaps the MonadLayerControl
instance for ListT
should just be dropped, and the documentation should clarify that a False
return from zero
indicates that the LayerState m a
contains exactly one a
in it, not more. It may be cleaner to enforce this invariant at the type level by replacing LayerState m a
with Either (BadState m) (a, GoodState m)
(and zero
with either True False
), since that seems like the only kind of LayerState
that will give the intended semantics.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.