polysemy 0.1.0.0 → 0.1.1.0
raw patch · 10 files changed
+92/−16 lines, 10 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Polysemy: data Lift m (z :: * -> *) a
- Polysemy.Internal: data Lift m (z :: * -> *) a
- Polysemy.Internal.Lift: Lift :: m a -> Lift m a
- Polysemy.Internal.Lift: [unLift] :: Lift m a -> m a
+ Polysemy: [Lift] :: {unLift :: m a} -> Lift m z a
+ Polysemy: newtype Lift m (z :: * -> *) a
+ Polysemy.IO: runIO :: forall m r a. (MonadIO m, Member (Lift m) r) => Semantic (Lift IO : r) a -> Semantic r a
+ Polysemy.Internal: [Lift] :: {unLift :: m a} -> Lift m z a
+ Polysemy.Internal: newtype Lift m (z :: * -> *) a
+ Polysemy.Internal.Lift: [Lift] :: {unLift :: m a} -> Lift m z a
- Polysemy: reinterpret3 :: FirstOrder e1 "reinterpret2" => (forall m x. e1 m x -> Semantic (e2 : (e3 : (e4 : r))) x) -> Semantic (e1 : r) a -> Semantic (e2 : (e3 : (e4 : r))) a
+ Polysemy: reinterpret3 :: FirstOrder e1 "reinterpret3" => (forall m x. e1 m x -> Semantic (e2 : (e3 : (e4 : r))) x) -> Semantic (e1 : r) a -> Semantic (e2 : (e3 : (e4 : r))) a
- Polysemy.Error: catch :: forall e_alUz a_alUB. forall r_am6p. Member (Error e_alUz) r_am6p => Semantic r_am6p a_alUB -> (e_alUz -> Semantic r_am6p a_alUB) -> Semantic r_am6p a_alUB
+ Polysemy.Error: catch :: forall e_alXs a_alXu. forall r_am9i. Member (Error e_alXs) r_am9i => Semantic r_am9i a_alXu -> (e_alXs -> Semantic r_am9i a_alXu) -> Semantic r_am9i a_alXu
- Polysemy.Error: throw :: forall e_alUw a_alUy. forall r_am6o. Member (Error e_alUw) r_am6o => e_alUw -> Semantic r_am6o a_alUy
+ Polysemy.Error: throw :: forall e_alXp a_alXr. forall r_am9h. Member (Error e_alXp) r_am9h => e_alXp -> Semantic r_am9h a_alXr
- Polysemy.Input: input :: forall i_aqKf. forall r_aqL0. Member (Input i_aqKf) r_aqL0 => Semantic r_aqL0 i_aqKf
+ Polysemy.Input: input :: forall i_aqN8. forall r_aqNT. Member (Input i_aqN8) r_aqNT => Semantic r_aqNT i_aqN8
- Polysemy.Internal.Combinators: reinterpret3 :: FirstOrder e1 "reinterpret2" => (forall m x. e1 m x -> Semantic (e2 : (e3 : (e4 : r))) x) -> Semantic (e1 : r) a -> Semantic (e2 : (e3 : (e4 : r))) a
+ Polysemy.Internal.Combinators: reinterpret3 :: FirstOrder e1 "reinterpret3" => (forall m x. e1 m x -> Semantic (e2 : (e3 : (e4 : r))) x) -> Semantic (e1 : r) a -> Semantic (e2 : (e3 : (e4 : r))) a
- Polysemy.Output: output :: forall o_aqva. forall r_aqvU. Member (Output o_aqva) r_aqvU => o_aqva -> Semantic r_aqvU ()
+ Polysemy.Output: output :: forall o_aqy3. forall r_aqyN. Member (Output o_aqy3) r_aqyN => o_aqy3 -> Semantic r_aqyN ()
- Polysemy.Random: random :: forall x_apS1. Random x_apS1 => forall r_apTt. Member Random r_apTt => Semantic r_apTt x_apS1
+ Polysemy.Random: random :: forall x_apUU. Random x_apUU => forall r_apWm. Member Random r_apWm => Semantic r_apWm x_apUU
- Polysemy.Random: randomR :: forall x_apS3. Random x_apS3 => forall r_apTu. Member Random r_apTu => (x_apS3, x_apS3) -> Semantic r_apTu x_apS3
+ Polysemy.Random: randomR :: forall x_apUW. Random x_apUW => forall r_apWn. Member Random r_apWn => (x_apUW, x_apUW) -> Semantic r_apWn x_apUW
- Polysemy.Reader: ask :: forall i_ar6k. forall r_ar7C. Member (Reader i_ar6k) r_ar7C => Semantic r_ar7C i_ar6k
+ Polysemy.Reader: ask :: forall i_ar9d. forall r_arav. Member (Reader i_ar9d) r_arav => Semantic r_arav i_ar9d
- Polysemy.Reader: local :: forall i_ar6m a_ar6o. forall r_ar7D. Member (Reader i_ar6m) r_ar7D => (i_ar6m -> i_ar6m) -> Semantic r_ar7D a_ar6o -> Semantic r_ar7D a_ar6o
+ Polysemy.Reader: local :: forall i_ar9f a_ar9h. forall r_araw. Member (Reader i_ar9f) r_araw => (i_ar9f -> i_ar9f) -> Semantic r_araw a_ar9h -> Semantic r_araw a_ar9h
- Polysemy.Resource: bracket :: forall a_XodF b_aodF. forall r_aoeF. Member Resource r_aoeF => Semantic r_aoeF a_XodF -> (a_XodF -> Semantic r_aoeF ()) -> (a_XodF -> Semantic r_aoeF b_aodF) -> Semantic r_aoeF b_aodF
+ Polysemy.Resource: bracket :: forall a_Xogy b_aogy. forall r_aohy. Member Resource r_aohy => Semantic r_aohy a_Xogy -> (a_Xogy -> Semantic r_aohy ()) -> (a_Xogy -> Semantic r_aohy b_aogy) -> Semantic r_aohy b_aogy
- Polysemy.State: get :: forall s_aoyA. forall r_aozL. Member (State s_aoyA) r_aozL => Semantic r_aozL s_aoyA
+ Polysemy.State: get :: forall s_aoBt. forall r_aoCE. Member (State s_aoBt) r_aoCE => Semantic r_aoCE s_aoBt
- Polysemy.State: put :: forall s_aoyC. forall r_aozM. Member (State s_aoyC) r_aozM => s_aoyC -> Semantic r_aozM ()
+ Polysemy.State: put :: forall s_aoBv. forall r_aoCF. Member (State s_aoBv) r_aoCF => s_aoBv -> Semantic r_aoCF ()
- Polysemy.Trace: trace :: forall r_art3. Member Trace r_art3 => String -> Semantic r_art3 ()
+ Polysemy.Trace: trace :: forall r_arvW. Member Trace r_arvW => String -> Semantic r_arvW ()
- Polysemy.Writer: censor :: forall o_arNO a_arNQ. forall r_arPF. Member (Writer o_arNO) r_arPF => (o_arNO -> o_arNO) -> Semantic r_arPF a_arNQ -> Semantic r_arPF a_arNQ
+ Polysemy.Writer: censor :: forall o_arQH a_arQJ. forall r_arSy. Member (Writer o_arQH) r_arSy => (o_arQH -> o_arQH) -> Semantic r_arSy a_arQJ -> Semantic r_arSy a_arQJ
- Polysemy.Writer: listen :: forall o_arNL a_XrNO. forall r_arPE. Member (Writer o_arNL) r_arPE => Semantic r_arPE a_XrNO -> Semantic r_arPE (o_arNL, a_XrNO)
+ Polysemy.Writer: listen :: forall o_arQE a_XrQH. forall r_arSx. Member (Writer o_arQE) r_arSx => Semantic r_arSx a_XrQH -> Semantic r_arSx (o_arQE, a_XrQH)
- Polysemy.Writer: tell :: forall o_arNJ. forall r_arPD. Member (Writer o_arNJ) r_arPD => o_arNJ -> Semantic r_arPD ()
+ Polysemy.Writer: tell :: forall o_arQC. forall r_arSw. Member (Writer o_arQC) r_arSw => o_arQC -> Semantic r_arSw ()
Files
- ChangeLog.md +11/−1
- README.md +2/−2
- bench/Poly.hs +18/−0
- polysemy.cabal +2/−1
- src/Polysemy.hs +5/−5
- src/Polysemy/IO.hs +41/−0
- src/Polysemy/Internal.hs +9/−2
- src/Polysemy/Internal/Combinators.hs +1/−1
- src/Polysemy/Internal/Lift.hs +2/−3
- src/Polysemy/Internal/Tactics.hs +1/−1
ChangeLog.md view
@@ -1,3 +1,13 @@-# Changelog for too-fast-too-free+# Changelog for polysemy++## 0.1.1.0 (2019-04-14)++- Added 'runIO' interpretation (thanks to @adamConnerSax)+- Minor documentation fixes+++## 0.1.0.0 (2019-04-11)++- Initial release ## Unreleased changes
README.md view
@@ -22,7 +22,7 @@ It's like `mtl` but composes better, requires less boilerplate, and avoids the O(n^2) instances problem. -It's like `freer-simple` but more powerful and 700x faster.+It's like `freer-simple` but more powerful and 35x faster. It's like `fused-effects` but with an order of magnitude less boilerplate. @@ -47,7 +47,7 @@ Console effect: ```haskell-{-# LANGAUGE TemplateHaskell #-}+{-# LANGUAGE TemplateHaskell #-} import Polysemy
bench/Poly.hs view
@@ -1,6 +1,8 @@+{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -fwarn-all-missed-specializations #-}@@ -11,6 +13,8 @@ import Polysemy.Error import Polysemy.Resource import Polysemy.State+import Polysemy.Input+import Polysemy.Output slowBeforeSpecialization :: Member (State Int) r => Semantic r Int@@ -42,4 +46,18 @@ . (runM .@ runResource .@@ runErrorInIO) . runState False $ prog++data Console m a where+ ReadLine :: Console m String+ WriteLine :: String -> Console m ()++makeSemantic ''Console++runConsoleBoring :: [String] -> Semantic (Console ': r) a -> Semantic r ([String], a)+runConsoleBoring inputs+ = runFoldMapOutput (:[])+ . runListInput inputs+ . reinterpret2 \case+ ReadLine -> maybe "" id <$> input+ WriteLine msg -> output msg
polysemy.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: polysemy-version: 0.1.0.0+version: 0.1.1.0 license: BSD3 license-file: LICENSE copyright: 2019 Sandy Maguire@@ -49,6 +49,7 @@ Polysemy.Internal.TH.Effect Polysemy.Internal.TH.Performance Polysemy.Internal.Union+ Polysemy.IO Polysemy.NonDet Polysemy.Output Polysemy.Random
src/Polysemy.hs view
@@ -8,17 +8,17 @@ , runM -- * Interoperating With Other Monads- , Lift ()+ , Lift (..) , sendM -- * Lifting , raise -- * Creating New Effects- -- | Effects should be defined as a GADT (enable @-XGADTs@), with kind @(* -> *) -> *@.- -- Every primitive action in the effect should be its own constructor of- -- the type. For example, we can model an effect which interacts with a tty- -- console as follows:+ -- | Effects should be defined as a GADT (enable @-XGADTs@), with kind @(*+ -- -> *) -> * -> *@. Every primitive action in the effect should be its+ -- own constructor of the type. For example, we can model an effect which+ -- interacts with a tty console as follows: -- -- @ -- data Console m a where
+ src/Polysemy/IO.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE AllowAmbiguousTypes #-}++module Polysemy.IO+ ( -- * Interpretations+ runIO+ ) where++import Polysemy+import Control.Monad.IO.Class+++------------------------------------------------------------------------------+-- | The 'MonadIO' class is conceptually an interpretation of 'IO' to some+-- other monad. This function reifies that intuition, by transforming an 'IO'+-- effect into some other 'MonadIO'.+--+-- This function is especially useful when using the 'MonadIO' instance for+-- 'Semantic' instance.+--+-- Make sure to type-apply the desired 'MonadIO' instance when using 'runIO'.+--+-- @since 0.1.1.0+--+-- ==== Example+--+-- @+-- foo :: PandocIO ()+-- foo = 'runM' . 'runIO' @PandocIO $ do+-- 'liftIO' $ putStrLn "hello from polysemy"+-- @+--+runIO+ :: forall m r a+ . ( MonadIO m+ , Member (Lift m) r+ )+ => Semantic (Lift IO ': r) a+ -> Semantic r a+runIO = interpret $ sendM . liftIO @m . unLift+{-# INLINE runIO #-}+
src/Polysemy/Internal.hs view
@@ -11,7 +11,7 @@ , run , runM , raise- , Lift ()+ , Lift (..) , usingSemantic , liftSemantic , hoistSemantic@@ -63,7 +63,7 @@ -- monomorphic representation of the @r@ parameter. -- -- After all of your effects are handled, you'll be left with either--- a @'Semantic' '[] a@ or a @'Semantic' ('Lift' m) a@ value, which can be+-- a @'Semantic' '[] a@ or a @'Semantic' '[ 'Lift' m ] a@ value, which can be -- consumed respectively by 'run' and 'runM'. -- -- ==== Examples@@ -162,18 +162,25 @@ instance (Member NonDet r) => Alternative (Semantic r) where empty = send Empty+ {-# INLINE empty #-} a <|> b = do send (Choose id) >>= \case False -> a True -> b+ {-# INLINE (<|>) #-} +------------------------------------------------------------------------------+-- | This instance will only lift 'IO' actions. If you want to lift into some+-- other 'MonadIO' type, use this instance, and handle it via the+-- 'Polysemy.IO.runIO' interpretation. instance (Member (Lift IO) r) => MonadIO (Semantic r) where liftIO = sendM {-# INLINE liftIO #-} instance Member Fixpoint r => MonadFix (Semantic r) where mfix f = send $ Fixpoint f+ {-# INLINE mfix #-} liftSemantic :: Union r (Semantic r) a -> Semantic r a
src/Polysemy/Internal/Combinators.hs view
@@ -219,7 +219,7 @@ ------------------------------------------------------------------------------ -- | Like 'reinterpret', but introduces /three/ intermediary effects. reinterpret3- :: FirstOrder e1 "reinterpret2"+ :: FirstOrder e1 "reinterpret3" => (∀ m x. e1 m x -> Semantic (e2 ': e3 ': e4 ': r) x) -- ^ A natural transformation from the handled effect to the new effects. -> Semantic (e1 ': r) a
src/Polysemy/Internal/Lift.hs view
@@ -23,7 +23,6 @@ -- -- Consider using 'Polysemy.Trace.trace' and 'Polysemy.Trace.runTraceIO' as -- a substitute for using 'putStrLn' directly.-newtype Lift m (z :: * -> *) a = Lift- { unLift :: m a- }+newtype Lift m (z :: * -> *) a where+ Lift :: { unLift :: m a } -> Lift m z a
src/Polysemy/Internal/Tactics.hs view
@@ -68,7 +68,7 @@ -- block will not be visible inside of the @dealloc@ block. -- -- Power users may explicitly use 'getInitialStateT' and 'bindT' to construct--- whatever data flow they'd like; although this is usually necessary.+-- whatever data flow they'd like; although this is usually unnecessary. type Tactical e m r x = ∀ f. (Functor f, Typeable1 f) => Semantic (WithTactics e f m r) (f x)