{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Miso.Effect
(
Effect
, Sub
, Sink
, DOMRef
, ComponentInfo (..)
, ComponentId
, mkComponentInfo
, (<#)
, (#>)
, batch
, batch_
, io
, io_
, for
, issue
, withSink
, mapSub
, noop
, runEffect
, scheduleIO
, scheduleIO_
, scheduleIOFor_
, scheduleSub
, effectSub
, batchEff
, noEff
) where
import Data.Foldable (for_)
import Control.Monad.RWS ( RWS, put, tell, execRWS )
import Language.Javascript.JSaddle (JSVal)
#if __GLASGOW_HASKELL__ <= 881
import qualified Control.Monad.Fail as Fail
import Data.Functor.Identity (Identity(..))
#endif
import Miso.FFI.Internal (JSM)
mkComponentInfo
:: ComponentId
-> DOMRef
-> ComponentInfo parent
mkComponentInfo :: forall parent. ComponentId -> DOMRef -> ComponentInfo parent
mkComponentInfo = ComponentId -> DOMRef -> ComponentInfo parent
forall parent. ComponentId -> DOMRef -> ComponentInfo parent
ComponentInfo
data ComponentInfo parent
= ComponentInfo
{ forall parent. ComponentInfo parent -> ComponentId
_componentId :: ComponentId
, forall parent. ComponentInfo parent -> DOMRef
_componentDOMRef :: DOMRef
}
type ComponentId = Int
type Sub action = Sink action -> JSM ()
type Sink action = action -> JSM ()
infixl 0 <#
(<#) :: model -> JSM action -> Effect parent model action
<# :: forall model action parent.
model -> JSM action -> Effect parent model action
(<#) model
m JSM action
action = model
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put model
m RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall a b.
RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity a
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity b
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Sink action -> JSM ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell [ \Sink action
f -> Sink action
f Sink action -> JSM action -> JSM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< JSM action
action ]
infixr 0 #>
(#>) :: JSM action -> model -> Effect parent model action
#> :: forall action model parent.
JSM action -> model -> Effect parent model action
(#>) = (model -> JSM action -> Effect parent model action)
-> JSM action -> model -> Effect parent model action
forall a b c. (a -> b -> c) -> b -> a -> c
flip model -> JSM action -> Effect parent model action
forall model action parent.
model -> JSM action -> Effect parent model action
(<#)
batch :: [JSM action] -> Effect parent model action
batch :: forall action parent model.
[JSM action] -> Effect parent model action
batch [JSM action]
actions = [RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
[ [Sink action -> JSM ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell [ \Sink action
f -> Sink action
f Sink action -> JSM action -> JSM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< JSM action
action ]
| JSM action
action <- [JSM action]
actions
]
batch_ :: [JSM ()] -> Effect parent model action
batch_ :: forall parent model action. [JSM ()] -> Effect parent model action
batch_ [JSM ()]
actions = [RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_
[ [Sink action -> JSM ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell [ JSM () -> Sink action -> JSM ()
forall a b. a -> b -> a
const JSM ()
action ]
| JSM ()
action <- [JSM ()]
actions
]
type Effect parent model action = RWS (ComponentInfo parent) [Sink action -> JSM ()] model ()
type DOMRef = JSVal
#if __GLASGOW_HASKELL__ <= 881
instance Fail.MonadFail Identity where
fail = error
#endif
runEffect
:: Effect parent model action
-> ComponentInfo parent
-> model
-> (model, [Sink action -> JSM ()])
runEffect :: forall parent model action.
Effect parent model action
-> ComponentInfo parent
-> model
-> (model, [Sink action -> JSM ()])
runEffect = RWS (ComponentInfo parent) [Sink action -> JSM ()] model ()
-> ComponentInfo parent
-> model
-> (model, [Sink action -> JSM ()])
forall r w s a. RWS r w s a -> r -> s -> (s, w)
execRWS
mapSub :: (a -> b) -> Sub a -> Sub b
mapSub :: forall a b. (a -> b) -> Sub a -> Sub b
mapSub a -> b
f Sub a
sub = \Sink b
g -> Sub a
sub (Sink b
g Sink b -> (a -> b) -> a -> JSM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
io :: JSM action -> Effect parent model action
io :: forall action parent model.
JSM action -> Effect parent model action
io JSM action
action = (Sink action -> JSM ()) -> Effect parent model action
forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink (JSM action
action JSM action -> Sink action -> JSM ()
forall a b. JSM a -> (a -> JSM b) -> JSM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=)
io_ :: JSM () -> Effect parent model action
io_ :: forall parent model action. JSM () -> Effect parent model action
io_ JSM ()
action = (Sink action -> JSM ()) -> Effect parent model action
forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink (\Sink action
_ -> JSM ()
action)
for :: Foldable f => JSM (f action) -> Effect parent model action
for :: forall (f :: * -> *) action parent model.
Foldable f =>
JSM (f action) -> Effect parent model action
for JSM (f action)
actions = (Sink action -> JSM ()) -> Effect parent model action
forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink ((Sink action -> JSM ()) -> Effect parent model action)
-> (Sink action -> JSM ()) -> Effect parent model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> JSM (f action)
actions JSM (f action) -> (f action -> JSM ()) -> JSM ()
forall a b. JSM a -> (a -> JSM b) -> JSM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (f action -> Sink action -> JSM ())
-> Sink action -> f action -> JSM ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip f action -> Sink action -> JSM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Sink action
sink
withSink :: (Sink action -> JSM ()) -> Effect parent model action
withSink :: forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink Sink action -> JSM ()
f = [Sink action -> JSM ()]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell [ Sink action -> JSM ()
f ]
issue :: action -> Effect parent model action
issue :: forall action parent model. action -> Effect parent model action
issue action
action = [(action -> JSM ()) -> JSM ()]
-> RWST
(ComponentInfo parent)
[(action -> JSM ()) -> JSM ()]
model
Identity
()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell [ \action -> JSM ()
f -> action -> JSM ()
f action
action ]
{-# DEPRECATED scheduleIO "Please use 'io' instead" #-}
scheduleIO :: JSM action -> Effect parent model action
scheduleIO :: forall action parent model.
JSM action -> Effect parent model action
scheduleIO = JSM action -> Effect parent model action
forall action parent model.
JSM action -> Effect parent model action
io
{-# DEPRECATED scheduleIO_ "Please use 'io_' instead" #-}
scheduleIO_ :: JSM () -> Effect parent model action
scheduleIO_ :: forall parent model action. JSM () -> Effect parent model action
scheduleIO_ = JSM () -> Effect parent model action
forall parent model action. JSM () -> Effect parent model action
io_
{-# DEPRECATED scheduleIOFor_ "Please use 'for' instead" #-}
scheduleIOFor_ :: Foldable f => JSM (f action) -> Effect parent model action
scheduleIOFor_ :: forall (f :: * -> *) action parent model.
Foldable f =>
JSM (f action) -> Effect parent model action
scheduleIOFor_ = JSM (f action) -> Effect parent model action
forall (f :: * -> *) action parent model.
Foldable f =>
JSM (f action) -> Effect parent model action
for
{-# DEPRECATED scheduleSub "Please use 'withSink' instead" #-}
scheduleSub :: (Sink action -> JSM ()) -> Effect parent model action
scheduleSub :: forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
scheduleSub = (Sink action -> JSM ()) -> Effect parent model action
forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink
{-# DEPRECATED effectSub "Please use 'put' and 'withSink' instead " #-}
effectSub :: model -> (Sink action -> JSM ()) -> Effect parent model action
effectSub :: forall model action parent.
model -> (Sink action -> JSM ()) -> Effect parent model action
effectSub model
m Sink action -> JSM ()
s = model
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put model
m RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall a b.
RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity a
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity b
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Sink action -> JSM ())
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall action parent model.
(Sink action -> JSM ()) -> Effect parent model action
withSink Sink action -> JSM ()
s
{-# DEPRECATED noEff "Please use 'put' instead " #-}
noEff :: model -> Effect parent model action
noEff :: forall model parent action. model -> Effect parent model action
noEff = model
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put
{-# DEPRECATED batchEff "Please use 'put' and 'batch' instead " #-}
batchEff :: model -> [JSM action] -> Effect parent model action
batchEff :: forall model action parent.
model -> [JSM action] -> Effect parent model action
batchEff model
model [JSM action]
actions = do
model
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put model
model
[JSM action]
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity ()
forall action parent model.
[JSM action] -> Effect parent model action
batch [JSM action]
actions
noop :: action -> Effect parent model action
noop :: forall action parent model. action -> Effect parent model action
noop = Effect parent model action -> action -> Effect parent model action
forall a b. a -> b -> a
const (() -> Effect parent model action
forall a.
a
-> RWST
(ComponentInfo parent) [Sink action -> JSM ()] model Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())