Skip to content

Question: dispatch signature #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BartAdv opened this issue Jan 17, 2017 · 6 comments
Open

Question: dispatch signature #5

BartAdv opened this issue Jan 17, 2017 · 6 comments

Comments

@BartAdv
Copy link

BartAdv commented Jan 17, 2017

Hi,

I'm having troubles figuring out why exactly the type of dispatch is polymorphic over f: f action -> f action. Does it has anything with middleware? If so, how could I put it to greater use? Async actions?

Currently in my code I've got couple of invocations like void $ dispatch $ pure $ Login $ Login.AttemptLogin $ LoginData { username: mail, password } and f is mostly inferred to be (redux :: REDUX | eff) for all eff.

@ethul
Copy link
Owner

ethul commented Jan 17, 2017

When I started working on this, I was experimenting a bit and giving some flexibility in the types since I wasn't precisely sure how I would ultimately end up using this representation. I agree that f is mostly going to be Eff, but I suppose the intention is to have f free to be other MonadEff instances in case the user requires the ability to dispatch an action in a monad besides Eff. An example you mentioned could be when using Aff.

@BartAdv
Copy link
Author

BartAdv commented Jan 17, 2017

OK, but how about the fact it's not merely an f Action, it is a f Action -> f Action?

@BartAdv
Copy link
Author

BartAdv commented Jan 17, 2017

Let's discuss with example:

    render dispatch this = do
      props <- React.getProps this
      pure $ loginView { onClick: \({ mail, password }) -> do
                                                             log "test"
                                                             void $ dispatch $ pure $ Login $ Login.AttemptLogin $ LoginData { username: mail, password }
                       , enabled: not props.inProgress && isNothing props.authData }

Here, f becomes:

Eff                                     
  ( "props" :: ReactProps               
  , "refs" :: ReactRefs (() :: # Effect)
  , "state" :: ReactState               
                 ( "read" :: Read       
                 )                      
  , "console" :: CONSOLE                
  , "props" :: ReactProps               
  , "refs" :: ReactRefs                 
                ( "read" :: Read        
                )                       
  , "state" :: ReactState               
                 ( "read" :: Read       
                 , "write" :: Write     
                 )                      
  | t0                                  
  )                                     

Now, the type of the render is:

type Render props state eff f action = (f action -> f action) -> React.Render props state eff

this means, our dispatch now works within the Eff that's provided by the onClick handler. So far so good, but now I'm feeding it with pure $ Login .... and that probably always is going to be pure, because if I want any effects I can do this in the onClick handler.

Therefore, I think the signature Action -> f Action could be more appropriate. But then I'm not sure why we need to return an Action at all (vanilla redux seems to be doing this, I'm not sure what for, is it only for convenience? Does dispatch always return an action, or can it return something else depending on middleware?)

Alternatively, I guess it would be g Action -> f Action, meaning it should be some effect that would be executed in a context of a store (again, middleware?), but then I'm not sure what could it potentially be.

// EDIT: hmm, maybe current signature makes it more convenient should one employ action creators - it would mean they could be effectful too...

@ethul
Copy link
Owner

ethul commented Jan 18, 2017

Thanks for the example. I don't really have a strong argument for f Action -> f Action or Action -> Action. I suppose the original idea was to keep things flexible for how actions are obtained. I admit that I have only really been doing void (dispatch (pure action))).

Maybe adding a function createClassEff could be useful where f would be Eff eff?

On the note of returning the action from the dispatch call, I just followed what redux does in this case. Again, I don't have a strong argument for this either way.

@BartAdv
Copy link
Author

BartAdv commented Jan 19, 2017

I suppose I'm gonna leave it as it's now and just wait to gather more use cases.

@BartAdv BartAdv closed this as completed Jan 19, 2017
@ethul
Copy link
Owner

ethul commented Jan 22, 2017

I think I'd like to reopen this.

I want to explore an idea for how to better utilize the f type.

I will post my thoughts here once I work them out a bit more.

@ethul ethul reopened this Jan 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants