Run
- Package
- purescript-run
- Repository
- natefaubion/purescript-run
#Run Source
newtype Run r aAn extensible effect Monad, indexed by a set of effect functors. Effects are eliminated by interpretation into a pure value or into some base effect Monad.
An example using State and Except:
type MyEffects =
( STATE Int
+ EXCEPT String
+ EFFECT
+ ()
)
yesProgram :: Run MyEffects Unit
yesProgram = do
whenM (gets (_ < 0)) do
throw "Number is less than 0"
whileM_ (gets (_ > 0)) do
liftEffect $ log "Yes"
modify (_ - 1)
where
whileM_
:: forall a
. Run MyEffects Boolean
-> Run MyEffects a
-> Run MyEffects Unit
whileM_ mb ma = flip tailRecM unit \a ->
mb >>= if _ then ma $> Loop unit else pure $ Done unit
main =
yesProgram
# catch (liftEffect <<< log)
# runState 10
# runBaseEffect
# void
Constructors
Instances
Newtype (Run r a) _Functor (Run r)Apply (Run r)Applicative (Run r)Bind (Run r)Monad (Run r)MonadRec (Run r)(TypeEquals (Proxy r1) (Proxy (EFFECT r2))) => MonadEffect (Run r1)(TypeEquals (Proxy r1) (Proxy (RowApply AFF (RowApply EFFECT r2)))) => MonadAff (Run r1)This will insert an
EFFECTeffect becauseMonadAffentailsMonadEffect. If you don't want this, useRun.liftAffrather thanControl.Monad.Aff.Class.liftAff.(TypeEquals (Proxy r1) (Proxy (RowApply CHOOSE r2))) => Alt (Run r1)(TypeEquals (Proxy r1) (Proxy (RowApply CHOOSE r2))) => Plus (Run r1)(TypeEquals (Proxy r1) (Proxy (RowApply CHOOSE r2))) => Alternative (Run r1)
#interpretRec Source
interpretRec :: forall m a r. MonadRec m => ((VariantF r) ~> m) -> Run r a -> m aExtracts the value from a program via some MonadRec m, preserving
stack safety.
#runAccumCont Source
runAccumCont :: forall m r s a b. (s -> VariantF r (s -> m b) -> m b) -> (s -> a -> m b) -> s -> Run r a -> m bExtracts the value from a program via some m using continuation passing
with an internal accumulator.
#runAccumPure Source
runAccumPure :: forall r1 r2 a b s. (s -> VariantF r1 (Run r1 a) -> Step (Tuple s (Run r1 a)) (VariantF r2 (Run r1 a))) -> (s -> a -> b) -> s -> Run r1 a -> Run r2 bEliminates effects purely with an internal accumulator. Uses Step from
Control.Monad.Rec.Class to preserve stack safety under tail recursion.
#expand Source
expand :: forall r1 r2 rx a. Union r1 rx r2 => Run r1 a -> Run r2 aCasts some set of effects to a wider set of effects via a left-biased union. For example, you could take a closed effect and unify it with a superset of effects because we know the additional effects never occur.
type LessRows = (foo :: Foo)
type MoreRows = (foo :: Foo, bar :: Bar, baz :: Baz)
foo :: Run LessRows Unit
foo = foo
foo' :: Run MoreRows Unit
foo' = expand foo
Re-exports from Control.Monad.Rec.Class
Re-exports from Data.Functor.Variant
#VariantF Source
data VariantF f aInstances
Functor (VariantF r)(RowToList row rl, FoldableVFRL rl row) => Foldable (VariantF row)(RowToList row rl, TraversableVFRL rl row) => Traversable (VariantF row)(RowToList r rl, VariantTags rl, VariantFShows rl a, Show a) => Show (VariantF r a)
#onMatch Source
onMatch :: forall rl r r1 r2 r3 a b. RowToList r rl => VariantFMatchCases rl r1 a b => Union r1 r2 r3 => Record r -> (VariantF r2 a -> b) -> VariantF r3 a -> bMatch a VariantF with a Record containing functions for handling cases.
This is similar to on, except instead of providing a single label and
handler, you can provide a record where each field maps to a particular
VariantF case.
onMatch
{ foo: \foo -> "Foo: " <> maybe "nothing" id foo
, bar: \bar -> "Bar: " <> snd bar
}
Polymorphic functions in records (such as show or id) can lead
to inference issues if not all polymorphic variables are specified
in usage. When in doubt, label methods with specific types, such as
show :: Int -> String, or give the whole record an appropriate type.
#match Source
match :: forall rl r r1 r2 a b. RowToList r rl => VariantFMatchCases rl r1 a b => Union r1 () r2 => Record r -> VariantF r2 a -> bCombinator for exhaustive pattern matching using an onMatch case record.
matchFn :: VariantF (foo :: Maybe, bar :: Tuple String, baz :: Either String) Int -> String
matchFn = match
{ foo: \foo -> "Foo: " <> maybe "nothing" show foo
, bar: \bar -> "Bar: " <> show (snd bar)
, baz: \baz -> "Baz: " <> either id show baz
}
#default Source
default :: forall a b r. a -> VariantF r b -> aCombinator for partial matching with a default value in case of failure.
caseFn :: forall r. VariantF (foo :: Maybe, bar :: Tuple String | r) Int -> String
caseFn = default "No match"
# on (Proxy :: Proxy "foo") (\foo -> "Foo: " <> maybe "nothing" show foo)
# on (Proxy :: Proxy "bar") (\bar -> "Bar: " <> show (snd bar))
#case_ Source
case_ :: forall a b. VariantF () a -> bCombinator for exhaustive pattern matching.
caseFn :: VariantF (foo :: Maybe, bar :: Tuple String, baz :: Either String) Int -> String
caseFn = case_
# on (Proxy :: Proxy "foo") (\foo -> "Foo: " <> maybe "nothing" show foo)
# on (Proxy :: Proxy "bar") (\bar -> "Bar: " <> show (snd bar))
# on (Proxy :: Proxy "baz") (\baz -> "Baz: " <> either id show baz)
This instance is provided for compatibility, but is otherwise unnecessary. You can use monadic recursion with
Run, deferring theMonadRecconstraint till it is interpretted.