packages feed

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 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)