Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds recipe CapabilityPatternWithCheckedExceptions #262

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tidy up and renaming, pointfree runApp
  • Loading branch information
afcondon committed Jan 5, 2021
commit fc3fa19509de47b41f444b7dc65928ad46a0c87c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ An enhancement of the CapabilityPattern Recipe, which adds `typed-exceptions`

It's best to be completely familiar with the design and implementation of that Cookbook recipe before looking at this one.

Additionally, you should familiarize yourself with the README from `checked-exceptions`.
Additionally, you should familiarize yourself with the [README](https://github.com/natefaubion/purescript-checked-exceptions) from `checked-exceptions`.


## Expected Behavior:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
, "assert"
, "console"
, "effect"
, "node-fs"
, "node-fs-aff"
, "node-readline"
, "transformers"
, "checked-exceptions"
, "typelevel-prelude"
]
, packages = ../../packages.dhall
, sources = [ "recipes/CapabilityPatternWithCheckedExceptionsNode/src/**/*.purs" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module CapabilityPatternWithCheckedExceptionsNode.Main where
import Prelude

import App.Application (program)
import App.ProductionExcV as AppExcV
import App.ProductionExcV as AppExcVM
import Effect (Effect)
import Effect.Aff (launchAff_)

Expand All @@ -12,5 +12,5 @@ import Effect.Aff (launchAff_)
-- | Layer 0 - Running the `program` in this context
main :: Effect Unit
main = launchAff_ do
result <- AppExcV.runApp program { url: "http://www.purescript.org"}
result <- AppExcVM.runApp program { url: "http://www.purescript.org"}
pure unit
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import Effect.Aff (Aff, error)
import Effect.Aff.Class (class MonadAff)
import Effect.Class (class MonadEffect, liftEffect)
import Effect.Class.Console as Console
import Node.Path (FilePath)
import Prim.RowList (class RowToList)
import Service.FS (class MonadFs, FsError)
import Service.FS (write) as FS
Expand All @@ -25,59 +24,52 @@ import Type.Data.Row (RProxy)
import Type.Equality (class TypeEquals, from)
import Type.Row (type (+))



-- the type that we expect to be in the ReaderT as our environment
type Environment = { url :: String }

-- | Aff wrapped in ExceptV wrapped in ReaderT
newtype AppExcV var a = AppExcV (ReaderT Environment (ExceptV var Aff) a)

-- newtype AppMA a = AppMA (ReaderT Environment Aff a)

-- runApp :: forall a. AppMA a -> Environment -> Aff a
-- runApp (AppMA reader_T) env = runReaderT reader_T env
newtype AppExcVM var a = AppExcVM (ReaderT Environment (ExceptV var Aff) a)

-- | ...and the means to run computations in it
runApp :: forall a. AppExcV () a -> Environment -> Aff a
runApp rave env = runAppExcV (RProxy :: _ ()) env rave
runApp :: forall a. AppExcVM () a -> Environment -> Aff a
runApp = runAppExcVM (RProxy :: _ ())
where
runAppExcV :: forall var rl.
runAppExcVM :: forall var rl.
RowToList var rl =>
VariantTags rl =>
VariantShows rl =>
RProxy var ->
AppExcVM var a ->
Environment ->
AppExcV var a ->
Aff a
runAppExcV _ env (AppExcV rave) = do
ran <- runExceptT $ runReaderT rave env
runAppExcVM _ (AppExcVM appExcVM) env = do
ran <- runExceptT $ runReaderT appExcVM env
case ran of
Right res -> pure res
Left l -> throwError $ error $ show l

-- | Layer 1 all the instances for the AppExcV monad
derive newtype instance raveMonadAff :: MonadAff (AppExcV var)
derive newtype instance raveMonadEffect :: MonadEffect (AppExcV var)
derive newtype instance raveMonad :: Monad (AppExcV var)
derive newtype instance raveApplicative :: Applicative (AppExcV var)
derive newtype instance raveApply :: Apply (AppExcV var)
derive newtype instance raveFunctor :: Functor (AppExcV var)
derive newtype instance raveBind :: Bind (AppExcV var)
derive newtype instance raveMonadError :: MonadThrow (Variant var) (AppExcV var)
Right result -> pure result
Left err -> throwError $ error $ show err

-- | Layer 1 all the instances for the AppExcVM monad
derive newtype instance monadAffAppExcVM :: MonadAff (AppExcVM var)
derive newtype instance monadEffectAppExcVM :: MonadEffect (AppExcVM var)
derive newtype instance monadAppExcVM :: Monad (AppExcVM var)
derive newtype instance applicativeAppExcVM :: Applicative (AppExcVM var)
derive newtype instance applyAppExcVM :: Apply (AppExcVM var)
derive newtype instance functorAppExcVM :: Functor (AppExcVM var)
derive newtype instance bindAppExcVM :: Bind (AppExcVM var)
derive newtype instance monadErrorAppExcVM :: MonadThrow (Variant var) (AppExcVM var)

-- | Capability instances
instance raveMonadHttp :: MonadHttp (AppExcV var)
instance monadHttpAppExcVM :: MonadHttp (AppExcVM var)

instance raveMonadFS :: MonadFs (AppExcV var)
instance monadFSAppExcVM :: MonadFs (AppExcVM var)

instance raveMonadAsk :: TypeEquals e1 Environment => MonadAsk e1 (AppExcV v) where
ask = AppExcV $ asks from
instance monadAskAppExcVM :: TypeEquals e1 Environment => MonadAsk e1 (AppExcVM v) where
ask = AppExcVM $ asks from

instance loggerAppExcV :: Logger (AppExcV var) where
instance loggerAppExcVM :: Logger (AppExcVM var) where
log msg = liftEffect $ Console.log msg

instance getUserNameAppExcV :: GetUserName (AppExcV var) where
instance getUserNameAppExcVM :: GetUserName (AppExcVM var) where
getUserName = do
env <- ask

Expand All @@ -104,7 +96,7 @@ getPureScript url = do
errorHandlersWithDefault :: forall m a.
MonadEffect m =>
a ->
{ fsFileNotFound :: FilePath -> m a
{ fsFileNotFound :: String -> m a
, fsPermissionDenied :: Unit -> m a
, httpNotFound :: Unit -> m a
, httpOther :: { body :: String, status :: Int} -> m a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import Prelude (class Monad, Unit, pure, unit)
import Type.Row (type (+))
import Control.Monad.Except.Checked (ExceptV)
import Data.Variant (SProxy(..), inj, Variant)
import Node.Path (FilePath)


-- | This module is an empty definition for an exception raising monadic interface to a file system

-- | Here's the fake file system monad for demonstration purposes
class (Monad m) <= MonadFs m

-- | dummy definition for FilePath, in reality you'd source from, for example, Node.FS
type FilePath = String

-- | we wish to export this checked-exception wrapper for some underlying FS operation
write ∷ ∀ r m. MonadFs m ⇒
FilePath → String → ExceptV (FsError + r) m Unit
Expand Down