Copyright | (C) 2016-2025 David M. Johnson |
---|---|
License | BSD3-style (see the file LICENSE) |
Maintainer | David M. Johnson <code@dmj.io> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Miso.Effect
Description
Synopsis
- type Effect model action = RWS ComponentName [Sink action -> JSM ()] model ()
- type Sub action = Sink action -> JSM ()
- type Sink action = action -> JSM ()
- (<#) :: model -> JSM action -> Effect model action
- (#>) :: JSM action -> model -> Effect model action
- batch :: [JSM action] -> Effect model action
- batch_ :: [JSM ()] -> Effect model action
- io :: JSM action -> Effect model action
- io_ :: JSM () -> Effect model action
- for :: Foldable f => JSM (f action) -> Effect model action
- issue :: action -> Effect model action
- withSink :: (Sink action -> JSM ()) -> Effect model action
- mapSub :: (a -> b) -> Sub a -> Sub b
- runEffect :: Effect model action -> MisoString -> model -> (model, [Sink action -> JSM ()])
- scheduleIO :: JSM action -> Effect model action
- scheduleIO_ :: JSM () -> Effect model action
- scheduleIOFor_ :: Foldable f => JSM (f action) -> Effect model action
- scheduleSub :: (Sink action -> JSM ()) -> Effect model action
- effectSub :: model -> (Sink action -> JSM ()) -> Effect model action
- batchEff :: model -> [JSM action] -> Effect model action
- noEff :: model -> Effect model action
Effect
Types
type Effect model action = RWS ComponentName [Sink action -> JSM ()] model () Source #
A monad for succinctly expressing model transitions in the update
function.
Effect
is a RWS
, where the State
abstracts over manually passing the model
around. It's also a Writer
Monad
, where the accumulator is a list of scheduled
IO
actions. Multiple actions can be scheduled using tell
from the mtl
library and a single action can be scheduled using io_
.
An Effect
represents the results of an update action.
It consists of the updated model and a list of subscriptions. Each Sub
is
run in a new thread so there is no risk of accidentally blocking the
application.
Tip: use the Effect
monad in combination with the stateful
lens
operators (all operators ending in "=
"). The following example assumes
the lenses field1
, counter
and field2
are in scope and that the
LambdaCase
language extension is enabled:
myComponent = Component { update = \case MyAction1 -> do field1 .= value1 counter += 1 MyAction2 -> do field2 %= f io_ $ do putStrLn "Hello" putStrLn "World!" , ... }
type Sink action = action -> JSM () Source #
Function to asynchronously dispatch actions to the update
function.
Combinators
(<#) :: model -> JSM action -> Effect model action infixl 0 Source #
Smart constructor for an Effect
with exactly one action.
(#>) :: JSM action -> model -> Effect model action infixr 0 Source #
Effect
smart constructor, flipped
batch :: [JSM action] -> Effect model action Source #
Smart constructor for an Effect
with multiple actions.
io_ :: JSM () -> Effect model action Source #
Like io_
but doesn't cause an action to be dispatched to
the update
function.
This is handy for scheduling IO
computations where you don't care
about their results or when they complete.
issue :: action -> Effect model action Source #
Issue a new Action
to be processed by update
.
update :: Action -> Effect Model Action update = \case Click -> issue HelloWorld
Since: 1.9.0.0
withSink :: (Sink action -> JSM ()) -> Effect model action Source #
withSink
allows users to access the sink of the Component
or top-level
Component
in their application. This is useful for introducing IO
into the system.
A synonym for tell
, specialized to Effect
.
A use-case is scheduling an IO
computation which creates a 3rd-party JS
widget which has an associated callback. The callback can then call the sink
to turn events into actions. To do this without accessing a sink requires
going via a
which introduces a leaky-abstraction.Sub
scription
update FetchJSON = withSink $ \sink -> getJSON (sink . ReceivedJSON) (sink . HandleError)
Internal
runEffect :: Effect model action -> MisoString -> model -> (model, [Sink action -> JSM ()]) Source #
Internal function used to unwrap an EffectCore
Deprecated
scheduleIOFor_ :: Foldable f => JSM (f action) -> Effect model action Source #
Deprecated: Please use for
instead
scheduleSub :: (Sink action -> JSM ()) -> Effect model action Source #
Deprecated: Please use withSink
instead