# Pastebin 5tL5O9MT diff --git a/Main.hs b/Main.hs index d973c8d..ce8dbb6 100644 --- a/Main.hs +++ b/Main.hs @@ -7,6 +7,11 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeOperators #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} module Main where @@ -16,6 +21,9 @@ import Polysemy.Error import qualified Control.Monad.Error as E import qualified Control.Monad.Reader as R +import qualified Control.Monad.Freer.Error as FE +import qualified Control.Monad.Freer as F + {- ############# polysemy ################ -} data Resource (m :: * -> *) a where @@ -36,13 +44,40 @@ result = run $ runError $ runErroringInt $ program {- ######### MTL ########### -} -program2 :: (E.MonadError String m, R.MonadReader Int m) => m Int -program2 = do - R.ask `E.catchError` const (pure 1) +class MonadResource m where + getInt' :: m Int + +program2 :: (E.MonadError String m, MonadResource m) => m Int +program2 = getInt' `E.catchError` const (pure 1) + +newtype ResourceT m a = ResourceT { runResourceT :: m a } + deriving (Functor, Applicative, Monad) + +deriving instance E.MonadError e m => E.MonadError e (ResourceT m) + +instance E.MonadError String m => MonadResource (ResourceT m) where + getInt' = ResourceT $ E.throwError "foo" result2 :: Either String Int -result2 = R.runReaderT program2 (error "error") -{- Right *** Exception: error -} +result2 = runResourceT program2 +{- Right 1 -} + +{- ######### Free ########### -} + +data ResourceF a where + GetInt' :: ResourceF Int + +getInt'' :: F.Member ResourceF effs => F.Eff effs Int +getInt'' = F.send GetInt' + +program3 :: (F.Member ResourceF effs, F.Member (FE.Error String) effs) => F.Eff effs Int +program3 = getInt'' `FE.catchError` \(_ :: String) -> pure 1 + +runErroringInt' :: F.Member (FE.Error String) effs => F.Eff (ResourceF ': effs) a -> F.Eff effs a +runErroringInt' = F.interpret $ \GetInt' -> FE.throwError "bar" + +result3 :: Either String Int +result3 = F.run $ FE.runError $ runErroringInt' program3 main :: IO () main = undefined diff --git a/poly.cabal b/poly.cabal index 7ae9941..582396e 100644 --- a/poly.cabal +++ b/poly.cabal @@ -19,4 +19,5 @@ executable poly , polysemy , polysemy-plugin , mtl + , freer-simple ghc-options: -fplugin=Polysemy.Plugin