3
votes

In my custom Halogen/Purescript project I follow the pattern from the AJAX Example where I split my actions up into pure Inputs and effectful Requests.

I want to change my event handler to use the preventDefault behavior, but don't understand what consequences for the type of the UI function this entails.

I made the same changes to the AJAX Example by changing the event handler the following way:

Before:

H.button [ A.classes [B.btn, B.btnPrimary]
         , A.disabled busy
         , A.onclick (\_ -> pure (handler code))
         ] [ H.text "Compile" ]

After:

H.a [ A.classes [B.btn, B.btnPrimary]
    , A.href "#compile"
    , A.disabled busy
    , A.onclick (\_ -> E.preventDefault $> pure (handler code))
    ] [ H.text "Compile" ]

(Full diff available here)

I end up with this type error:

Cannot unify type
    Example.Ajax.Input
    with type
        Halogen.HTML.Events.Monad.Event Halogen.HalogenEffects<(http ::
        Example.Ajax.HTTP | u32519)> Example.Ajax.Input

At this point, I'm a bit lost whether I would need to adjust the type signature of the UI function or I apply the preventDefault modifier the wrong way.

1

1 Answers

8
votes

The type of $> looks like:

($>) :: forall a. EventHandler a -> b -> EventHandler b

The type of pure looks like:

pure :: forall a. a -> EventHandler a

So the problem is by using both together, you're making a type which looks like this:

EventHandler a -> EventHandler b -> EventHandler (EventHandler b)

But you don't want that, you just want an EventHandler b, where b is the E.Event type of handler code.

The best solution is to just not use pure:

E.preventDefault $> handler code

If sometime you do have two EventHandler values you want to use together like this, the function to use is *> instead of $>.