module Halogen.Component where

import Data.Functor.Coyoneda (Coyoneda (..))
import Data.NT
import Data.Row (HasType, Row)
import HPrelude hiding (get)
import Halogen.Data.Slot hiding (pop)
import Halogen.Data.Slot qualified as Slot
import Halogen.HTML.Core
import Halogen.Query.HalogenM (HalogenM)
import Halogen.Query.HalogenM qualified as HM
import Halogen.Query.HalogenQ
import Halogen.VDom.Thunk hiding (hoist)
import Halogen.VDom.Thunk qualified as Thunk

data ComponentSlotBox slots m msg = forall query input output. ComponentSlotBox
  { ()
get :: forall slot. SlotStorage slots slot -> Maybe (slot query output)
  , ()
pop :: forall slot. SlotStorage slots slot -> Maybe (slot query output, SlotStorage slots slot)
  , ()
set :: forall slot. slot query output -> SlotStorage slots slot -> SlotStorage slots slot
  , ()
component :: Component query input output m
  , ()
input :: input
  , ()
output :: output -> Maybe msg
  }

deriving instance Functor (ComponentSlotBox slots' m)

data ComponentSlot (slots :: Row Type) m msg
  = ComponentSlot (ComponentSlotBox slots m msg)
  | ThunkSlot (Thunk (HTML (ComponentSlot slots m msg)) msg)

instance Functor (ComponentSlot slots' m) where
  fmap :: forall a b.
(a -> b) -> ComponentSlot slots' m a -> ComponentSlot slots' m b
fmap a -> b
f = \case
    ComponentSlot ComponentSlotBox slots' m a
box -> ComponentSlotBox slots' m b -> ComponentSlot slots' m b
forall (slots :: Row (*)) (m :: * -> *) msg.
ComponentSlotBox slots m msg -> ComponentSlot slots m msg
ComponentSlot (ComponentSlotBox slots' m b -> ComponentSlot slots' m b)
-> ComponentSlotBox slots' m b -> ComponentSlot slots' m b
forall a b. (a -> b) -> a -> b
$ (a -> b)
-> ComponentSlotBox slots' m a -> ComponentSlotBox slots' m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map a -> b
f ComponentSlotBox slots' m a
box
    ThunkSlot Thunk (HTML (ComponentSlot slots' m a)) a
t -> Thunk (HTML (ComponentSlot slots' m b)) b
-> ComponentSlot slots' m b
forall (slots :: Row (*)) (m :: * -> *) msg.
Thunk (HTML (ComponentSlot slots m msg)) msg
-> ComponentSlot slots m msg
ThunkSlot (Thunk (HTML (ComponentSlot slots' m b)) b
 -> ComponentSlot slots' m b)
-> Thunk (HTML (ComponentSlot slots' m b)) b
-> ComponentSlot slots' m b
forall a b. (a -> b) -> a -> b
$ (HTML (ComponentSlot slots' m a) a
 -> HTML (ComponentSlot slots' m b) b)
-> Thunk (HTML (ComponentSlot slots' m a)) a
-> Thunk (HTML (ComponentSlot slots' m b)) b
forall {k1} {k2} (f :: k1 -> *) (g :: k2 -> *) (i :: k1) (j :: k2).
(f i -> g j) -> Thunk f i -> Thunk g j
mapThunk ((ComponentSlot slots' m a -> ComponentSlot slots' m b)
-> (a -> b)
-> HTML (ComponentSlot slots' m a) a
-> HTML (ComponentSlot slots' m b) b
forall a b c d. (a -> b) -> (c -> d) -> HTML a c -> HTML b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((a -> b) -> ComponentSlot slots' m a -> ComponentSlot slots' m b
forall a b.
(a -> b) -> ComponentSlot slots' m a -> ComponentSlot slots' m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) a -> b
f) Thunk (HTML (ComponentSlot slots' m a)) a
t

data ComponentSpec' state query action slots input output m n = ComponentSpec
  { forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> input -> m state
initialState :: input -> m state
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> state -> HTML (ComponentSlot slots m action) action
render :: state -> HTML (ComponentSlot slots m action) action
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> HalogenQ query action input ~> n
eval :: HalogenQ query action input ~> n
  }

type ComponentSpec state query action slots input output m =
  ComponentSpec' state query action slots input output m (HalogenM state action slots output m)

data Component query input output m
  = forall model msg slots.
    Component (ComponentSpec model query msg slots input output m)

mkComponent :: forall state query action slots input output m. ComponentSpec state query action slots input output m -> Component query input output m
mkComponent :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
ComponentSpec state query action slots input output m
-> Component query input output m
mkComponent = ComponentSpec state query action slots input output m
-> Component query input output m
forall (query :: * -> *) input output (m :: * -> *) model msg
       (slots :: Row (*)).
ComponentSpec model query msg slots input output m
-> Component query input output m
Component

-- | Constructs a ComponentSlot
-- |
-- | Takes:
-- | - the slot address label
-- | - the slot address index
-- | - the component for the slot
-- | - the input value to pass to the component
-- | - a function mapping outputs from the component to a query in the parent
componentSlot
  :: forall label
    ->forall query input output slots m action slot
   . (HasType label (Slot query output slot) slots)
  => (KnownSymbol label)
  => (Ord slot)
  => slot
  -> Component query input output m
  -> input
  -> (output -> Maybe action)
  -> ComponentSlotBox slots m action
componentSlot :: forall (label :: Symbol) ->
forall (query :: * -> *) input output (slots :: Row (*))
       (m :: * -> *) action slot.
(HasType label (Slot query output slot) slots, KnownSymbol label,
 Ord slot) =>
slot
-> Component query input output m
-> input
-> (output -> Maybe action)
-> ComponentSlotBox slots m action
componentSlot label slot
p Component query input output m
component input
input output -> Maybe action
output =
  ComponentSlotBox
    { get :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
get = slot -> SlotStorage slots slot -> Maybe (slot query output)
(HasType label (Slot query output slot) slots, KnownSymbol label,
 Ord slot) =>
slot -> SlotStorage slots slot -> Maybe (slot query output)
forall (symb :: Symbol) ->
(HasType symb (Slot query output slot) slots, KnownSymbol symb,
 Ord slot) =>
slot -> SlotStorage slots slot -> Maybe (slot query output)
forall (query :: * -> *) output s (slots' :: Row (*))
       (slot :: (* -> *) -> * -> *).
forall (symb :: Symbol) ->
(HasType symb (Slot query output s) slots', KnownSymbol symb,
 Ord s) =>
s -> SlotStorage slots' slot -> Maybe (slot query output)
Slot.lookup label slot
p
    , pop :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
pop = slot
-> SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
(HasType label (Slot query output slot) slots, KnownSymbol label,
 Ord slot) =>
slot
-> SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
forall (symb :: Symbol) ->
(HasType symb (Slot query output slot) slots, KnownSymbol symb,
 Ord slot) =>
slot
-> SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
forall (query :: * -> *) output s (slots' :: Row (*))
       (slot :: (* -> *) -> * -> *).
forall (symb :: Symbol) ->
(HasType symb (Slot query output s) slots', KnownSymbol symb,
 Ord s) =>
s
-> SlotStorage slots' slot
-> Maybe (slot query output, SlotStorage slots' slot)
Slot.pop label slot
p
    , set :: forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
set = slot
-> slot query output
-> SlotStorage slots slot
-> SlotStorage slots slot
(HasType label (Slot query output slot) slots, KnownSymbol label,
 Ord slot) =>
slot
-> slot query output
-> SlotStorage slots slot
-> SlotStorage slots slot
forall (symb :: Symbol) ->
(HasType symb (Slot query output slot) slots, KnownSymbol symb,
 Ord slot) =>
slot
-> slot query output
-> SlotStorage slots slot
-> SlotStorage slots slot
forall (query :: * -> *) output s (slots' :: Row (*))
       (slot :: (* -> *) -> * -> *).
forall (symb :: Symbol) ->
(HasType symb (Slot query output s) slots', KnownSymbol symb,
 Ord s) =>
s
-> slot query output
-> SlotStorage slots' slot
-> SlotStorage slots' slot
Slot.insert label slot
p
    , Component query input output m
component :: Component query input output m
component :: Component query input output m
component
    , input
input :: input
input :: input
input
    , output -> Maybe action
output :: output -> Maybe action
output :: output -> Maybe action
output
    }

-- | Changes the Component's `m` type. A use case for this
-- | might be to interpret some `Free` monad as `IO` so the component can be
-- | used with `runUI`.
hoist
  :: forall query input output m m'
   . (Functor m')
  => (m ~> m')
  -> Component query input output m
  -> Component query input output m'
hoist :: forall (query :: * -> *) input output (m :: * -> *) (m' :: * -> *).
Functor m' =>
(m ~> m')
-> Component query input output m
-> Component query input output m'
hoist m ~> m'
nat (Component ComponentSpec {model -> HTML (ComponentSlot slots m msg) msg
render :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> state -> HTML (ComponentSlot slots m action) action
render :: model -> HTML (ComponentSlot slots m msg) msg
render, HalogenQ query msg input ~> HalogenM model msg slots output m
eval :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> HalogenQ query action input ~> n
eval :: HalogenQ query msg input ~> HalogenM model msg slots output m
eval, input -> m model
initialState :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *) (n :: * -> *).
ComponentSpec' state query action slots input output m n
-> input -> m state
initialState :: input -> m model
initialState}) =
  ComponentSpec model query msg slots input output m'
-> Component query input output m'
forall (query :: * -> *) input output (m :: * -> *) model msg
       (slots :: Row (*)).
ComponentSpec model query msg slots input output m
-> Component query input output m
Component
    (ComponentSpec model query msg slots input output m'
 -> Component query input output m')
-> ComponentSpec model query msg slots input output m'
-> Component query input output m'
forall a b. (a -> b) -> a -> b
$ ComponentSpec
      { initialState :: input -> m' model
initialState = (m ~> m') -> m model -> m' model
forall {k} (m :: k -> *) (n :: k -> *) (a :: k).
(m ~> n) -> m a -> n a
runNT m ~> m'
nat (m model -> m' model) -> (input -> m model) -> input -> m' model
forall b c a. (b -> c) -> (a -> b) -> a -> c
. input -> m model
initialState
      , render :: model -> HTML (ComponentSlot slots m' msg) msg
render = (ComponentSlot slots m msg -> ComponentSlot slots m' msg)
-> HTML (ComponentSlot slots m msg) msg
-> HTML (ComponentSlot slots m' msg) msg
forall a b c. (a -> b) -> HTML a c -> HTML b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((m ~> m')
-> ComponentSlot slots m msg -> ComponentSlot slots m' msg
forall (slots :: Row (*)) (m :: * -> *) (m' :: * -> *) action.
Functor m' =>
(m ~> m')
-> ComponentSlot slots m action -> ComponentSlot slots m' action
hoistSlot m ~> m'
nat) (HTML (ComponentSlot slots m msg) msg
 -> HTML (ComponentSlot slots m' msg) msg)
-> (model -> HTML (ComponentSlot slots m msg) msg)
-> model
-> HTML (ComponentSlot slots m' msg) msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. model -> HTML (ComponentSlot slots m msg) msg
render
      , eval :: HalogenQ query msg input ~> HalogenM model msg slots output m'
eval = (forall a.
 HalogenQ query msg input a -> HalogenM model msg slots output m' a)
-> HalogenQ query msg input ~> HalogenM model msg slots output m'
forall {k} (m :: k -> *) (n :: k -> *).
(forall (a :: k). m a -> n a) -> m ~> n
NT ((forall a.
  HalogenQ query msg input a -> HalogenM model msg slots output m' a)
 -> HalogenQ query msg input ~> HalogenM model msg slots output m')
-> (forall a.
    HalogenQ query msg input a -> HalogenM model msg slots output m' a)
-> HalogenQ query msg input ~> HalogenM model msg slots output m'
forall a b. (a -> b) -> a -> b
$ (m ~> m')
-> HalogenM model msg slots output m a
-> HalogenM model msg slots output m' a
forall state action (slots :: Row (*)) output (m :: * -> *)
       (m' :: * -> *) a.
Functor m' =>
(m ~> m')
-> HalogenM state action slots output m a
-> HalogenM state action slots output m' a
HM.hoist m ~> m'
nat (HalogenM model msg slots output m a
 -> HalogenM model msg slots output m' a)
-> (HalogenQ query msg input a
    -> HalogenM model msg slots output m a)
-> HalogenQ query msg input a
-> HalogenM model msg slots output m' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HalogenQ query msg input ~> HalogenM model msg slots output m)
-> HalogenQ query msg input a
-> HalogenM model msg slots output m a
forall {k} (m :: k -> *) (n :: k -> *) (a :: k).
(m ~> n) -> m a -> n a
runNT HalogenQ query msg input ~> HalogenM model msg slots output m
eval
      }

-- | The spec record that `mkEval` accepts to construct a component `eval`
-- | function.
-- |
-- | It's not a requirement to use `mkEval`, and sometimes it's preferrable
-- | to write a component `eval` function from scratch, but often `mkEval` is
-- | more convenient for common cases.
-- |
-- | See below for more details about `mkEval` and `defaultEval`.
data EvalSpec state query action slots input output m = EvalSpec
  { forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
-> action -> HalogenM state action slots output m ()
handleAction :: action -> HalogenM state action slots output m ()
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
-> forall a.
   query a -> HalogenM state action slots output m (Maybe a)
handleQuery :: forall a. query a -> HalogenM state action slots output m (Maybe a)
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
-> input -> Maybe action
receive :: input -> Maybe action
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m -> Maybe action
initialize :: Maybe action
  , forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m -> Maybe action
finalize :: Maybe action
  }

-- | A default value for `mkEval` that will result in an `eval` that nothing at
-- | all - all incoming actions and queries will be ignored, and no receiver,
-- | initializer, or finalizer will be specified.
-- |
-- | Usually this will be used with record update syntax to override fields to
-- | specify things as needed. If a component only needs to handle actions,
-- | for instance, a usage might be something like this:
-- |
-- | ```purescript
-- | H.mkComponent
-- |   { initialState
-- |   , render
-- |   , eval: H.mkEval (H.defaultEval { handleAction = ?handleAction })
-- |   }
-- | ```
defaultEval :: forall state query action slots input output m. EvalSpec state query action slots input output m
defaultEval :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
defaultEval =
  EvalSpec
    { handleAction :: action -> HalogenM state action slots output m ()
handleAction = HalogenM state action slots output m ()
-> action -> HalogenM state action slots output m ()
forall a b. a -> b -> a
const (() -> HalogenM state action slots output m ()
forall a. a -> HalogenM state action slots output m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
    , handleQuery :: forall a. query a -> HalogenM state action slots output m (Maybe a)
handleQuery = HalogenM state action slots output m (Maybe a)
-> query a -> HalogenM state action slots output m (Maybe a)
forall a b. a -> b -> a
const (Maybe a -> HalogenM state action slots output m (Maybe a)
forall a. a -> HalogenM state action slots output m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing)
    , receive :: input -> Maybe action
receive = Maybe action -> input -> Maybe action
forall a b. a -> b -> a
const Maybe action
forall a. Maybe a
Nothing
    , initialize :: Maybe action
initialize = Maybe action
forall a. Maybe a
Nothing
    , finalize :: Maybe action
finalize = Maybe action
forall a. Maybe a
Nothing
    }

-- | Accepts an `EvalSpec` to produce an `eval` function for a component. For
-- | example:
-- |
-- | ```purescript
-- | -- use `defaultEval` and override fields selectively
-- | H.mkEval (H.defaultEval { handleAction = ?handleAction })
-- |
-- | -- or specify all the fields in the `EvalSpec`
-- | H.mkEval
-- |   { handleAction: ?handleAction
-- |   , handleQuery: ?handleQuery
-- |   , receive: ?receive
-- |   , initialize: ?initialize
-- |   , finalize: ?finalize
-- |   }
-- | ```
mkEval
  :: forall state query action slots input output m
   . EvalSpec state query action slots input output m
  -> HalogenQ query action input
    ~> HalogenM state action slots output m
mkEval :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
-> HalogenQ query action input
   ~> HalogenM state action slots output m
mkEval args :: EvalSpec state query action slots input output m
args@EvalSpec {forall a. query a -> HalogenM state action slots output m (Maybe a)
handleQuery :: forall state (query :: * -> *) action (slots :: Row (*)) input
       output (m :: * -> *).
EvalSpec state query action slots input output m
-> forall a.
   query a -> HalogenM state action slots output m (Maybe a)
handleQuery :: forall a. query a -> HalogenM state action slots output m (Maybe a)
handleQuery} = (forall a.
 HalogenQ query action input a
 -> HalogenM state action slots output m a)
-> HalogenQ query action input
   ~> HalogenM state action slots output m
forall {k} (m :: k -> *) (n :: k -> *).
(forall (a :: k). m a -> n a) -> m ~> n
NT ((forall a.
  HalogenQ query action input a
  -> HalogenM state action slots output m a)
 -> HalogenQ query action input
    ~> HalogenM state action slots output m)
-> (forall a.
    HalogenQ query action input a
    -> HalogenM state action slots output m a)
-> HalogenQ query action input
   ~> HalogenM state action slots output m
forall a b. (a -> b) -> a -> b
$ \case
  Initialize a
a ->
    (action -> HalogenM state action slots output m ())
-> Maybe action -> HalogenM state action slots output m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ EvalSpec state query action slots input output m
args.handleAction EvalSpec state query action slots input output m
args.initialize HalogenM state action slots output m ()
-> a -> HalogenM state action slots output m a
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a
a
  Finalize a
a ->
    (action -> HalogenM state action slots output m ())
-> Maybe action -> HalogenM state action slots output m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ EvalSpec state query action slots input output m
args.handleAction EvalSpec state query action slots input output m
args.finalize HalogenM state action slots output m ()
-> a -> HalogenM state action slots output m a
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a
a
  Receive input
i a
a ->
    (action -> HalogenM state action slots output m ())
-> Maybe action -> HalogenM state action slots output m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ EvalSpec state query action slots input output m
args.handleAction (EvalSpec state query action slots input output m
args.receive input
i) HalogenM state action slots output m ()
-> a -> HalogenM state action slots output m a
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a
a
  Action action
action a
a ->
    EvalSpec state query action slots input output m
args.handleAction action
action HalogenM state action slots output m ()
-> a -> HalogenM state action slots output m a
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> a
a
  Query (Coyoneda b -> a
req query b
fct) () -> a
f ->
    (Maybe b -> a)
-> HalogenM state action slots output m (Maybe b)
-> HalogenM state action slots output m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (a -> (b -> a) -> Maybe b -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> a
f ()) b -> a
req) (HalogenM state action slots output m (Maybe b)
 -> HalogenM state action slots output m a)
-> (query b -> HalogenM state action slots output m (Maybe b))
-> query b
-> HalogenM state action slots output m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. query b -> HalogenM state action slots output m (Maybe b)
forall a. query a -> HalogenM state action slots output m (Maybe a)
handleQuery (query b -> HalogenM state action slots output m a)
-> query b -> HalogenM state action slots output m a
forall a b. (a -> b) -> a -> b
$ query b
fct

-- | Changes the ComponentSlot's `m` type.
hoistSlot
  :: forall slots m m' action
   . (Functor m')
  => (m ~> m')
  -> ComponentSlot slots m action
  -> ComponentSlot slots m' action
hoistSlot :: forall (slots :: Row (*)) (m :: * -> *) (m' :: * -> *) action.
Functor m' =>
(m ~> m')
-> ComponentSlot slots m action -> ComponentSlot slots m' action
hoistSlot m ~> m'
nat = \case
  ComponentSlot ComponentSlotBox {input
Component query input output m
output -> Maybe action
forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
get :: ()
pop :: ()
set :: ()
component :: ()
input :: ()
output :: ()
get :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
pop :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
set :: forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
component :: Component query input output m
input :: input
output :: output -> Maybe action
..} -> ComponentSlotBox slots m' action -> ComponentSlot slots m' action
forall (slots :: Row (*)) (m :: * -> *) msg.
ComponentSlotBox slots m msg -> ComponentSlot slots m msg
ComponentSlot (ComponentSlotBox slots m' action -> ComponentSlot slots m' action)
-> ComponentSlotBox slots m' action
-> ComponentSlot slots m' action
forall a b. (a -> b) -> a -> b
$ ComponentSlotBox {component :: Component query input output m'
component = (m ~> m')
-> Component query input output m
-> Component query input output m'
forall (query :: * -> *) input output (m :: * -> *) (m' :: * -> *).
Functor m' =>
(m ~> m')
-> Component query input output m
-> Component query input output m'
hoist m ~> m'
nat Component query input output m
component, input
output -> Maybe action
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
SlotStorage slots slot -> Maybe (slot query output)
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
get :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
pop :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
set :: forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
input :: input
output :: output -> Maybe action
get :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot -> Maybe (slot query output)
pop :: forall (slot :: (* -> *) -> * -> *).
SlotStorage slots slot
-> Maybe (slot query output, SlotStorage slots slot)
set :: forall (slot :: (* -> *) -> * -> *).
slot query output
-> SlotStorage slots slot -> SlotStorage slots slot
input :: input
output :: output -> Maybe action
..}
  ThunkSlot Thunk (HTML (ComponentSlot slots m action)) action
t ->
    Thunk (HTML (ComponentSlot slots m' action)) action
-> ComponentSlot slots m' action
forall (slots :: Row (*)) (m :: * -> *) msg.
Thunk (HTML (ComponentSlot slots m msg)) msg
-> ComponentSlot slots m msg
ThunkSlot (Thunk (HTML (ComponentSlot slots m' action)) action
 -> ComponentSlot slots m' action)
-> Thunk (HTML (ComponentSlot slots m' action)) action
-> ComponentSlot slots m' action
forall a b. (a -> b) -> a -> b
$ (forall x.
 HTML (ComponentSlot slots m action) x
 -> HTML (ComponentSlot slots m' action) x)
-> Thunk (HTML (ComponentSlot slots m action)) action
-> Thunk (HTML (ComponentSlot slots m' action)) action
forall {k} (f :: k -> *) (g :: k -> *) (a :: k).
(forall (x :: k). f x -> g x) -> Thunk f a -> Thunk g a
Thunk.hoist ((ComponentSlot slots m action -> ComponentSlot slots m' action)
-> HTML (ComponentSlot slots m action) x
-> HTML (ComponentSlot slots m' action) x
forall a b c. (a -> b) -> HTML a c -> HTML b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((m ~> m')
-> ComponentSlot slots m action -> ComponentSlot slots m' action
forall (slots :: Row (*)) (m :: * -> *) (m' :: * -> *) action.
Functor m' =>
(m ~> m')
-> ComponentSlot slots m action -> ComponentSlot slots m' action
hoistSlot m ~> m'
nat)) Thunk (HTML (ComponentSlot slots m action)) action
t