Functional reactive programming
Event miscellany
Because who likes to lift2 over append when you can just append?
One of the annoying bits of working with any functorial type is that, for basic operations, you constantly have to map
and lift2
. This gets un-fun after a while, so it's a common convention to add sensible instances of typeclasses related to the type a
in f a
provided that there's an unambiguous interpretation of what they mean. Thankfully, in the case of Event
, this is possible for many core typeclasses.
Semigroups
Events can be considered Semigroup
s if the underlying type is a Semigroup
. This follows the classic pattern of equating <>
with <*>
.
Events as semigroups
The example below shows how two events can be appended together to control classes in the DOM.
VITE_START=EventsAsSemigroups pnpm example
module Examples.EventsAsSemigroups where
import Prelude
import Deku.Toplevel (runInBody)
import Data.Tuple.Nested ((/\))
import Deku.DOM.Attributes as DA
import Deku.Toplevel (runInBody)
import Deku.Control (text_)
import Deku.DOM as D
import Deku.Do as Deku
import Deku.Hooks (useState')
import Deku.DOM.Listeners as DL
import Deku.Toplevel (runInBody)
import Effect (Effect)
import ExampleAssitant (ExampleSignature)
import Deku.Toplevel (runInBody)
buttonClass =
"""inline-flex items-center rounded-md
border border-transparent bg-indigo-600 px-3 py-2
text-sm font-medium leading-4 text-white shadow-sm
hover:bg-indigo-700 focus:outline-none focus:ring-2
focus:ring-indigo-500 focus:ring-offset-2 mr-6""" :: String
main :: Effect Unit
main = void $ runInBody Deku.do
setKlass1 /\ klass1 <- useState'
setKlass2 /\ klass2 <- useState'
let
button setter txt = D.button
[ DA.klass_ buttonClass, DL.click_ \_ -> (setter txt) ]
[ text_ txt ]
D.div_
[ D.div_ $
[ button setKlass1 "text-2xl"
, button setKlass1 "text-sm"
, button setKlass2 "text-orange-500"
, button setKlass2 "text-green-300"
]
, D.div_
[ D.span
[ DA.klass_ "text-sm text-green-500"
, DA.klass ((klass1 <#> (_ <> " ")) <> klass2)
]
[ text_ "Hello!" ]
]
]
Hello!
Events aren't monoids
Alas, Event a
is not a Monoid
because it has no Applicative
instance, so we can't do pure mempty
. If you really need a Monoid
out of an Event
, you can always useEndo
.