Skip to content
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

Would sum types work with your "One Last Pattern" section? #3

Closed
sdegutis opened this issue Feb 12, 2015 · 8 comments
Closed

Would sum types work with your "One Last Pattern" section? #3

sdegutis opened this issue Feb 12, 2015 · 8 comments

Comments

@sdegutis
Copy link

In your "One Last Pattern" you seem to suggest changing the update function's signature to allow specific use-cases to return more context than just an updated model. But for many different actions, this can get out of hand quickly. Would using sum types be appropriate here instead?

@evancz
Copy link
Owner

evancz commented Feb 12, 2015

Yes, totally! I just wrote up an internal document for Prezi that shows "the most general version" of update:

update : UpdateContext -> Action -> Model -> (Model, Effect)

-- whatever other information is owned by a parent module
type alias UpdateContext =
    { userName : String
    , ...
    }

-- request effects from the parent module
type Effect = Print | LoadUserPicture | ...

One cool thing about this is that it makes it super easy to cache and batch HTTP and database requests. If 4 different pieces need the user picture, we can be abstract about requesting it, and at the top create a cache of recently loaded images so we can skip the request.

I'll be writing about this for real as soon as I can!

@evancz
Copy link
Owner

evancz commented Feb 12, 2015

The true most general version is probably like this:

update : UpdateContext -> Action -> Model -> (Maybe Model, Effect)

Which would let you delete yourself. I guess that could be exposed through the Effect union type as well though, so maybe this is isomorphic to the most general version :)

Do these comments clarify things? I think the big message is that you can be quite flexible in the return type to cover your particular case. I don't yet know "the one best way to do it" yet.

@sdegutis
Copy link
Author

Do these comments clarify things?

Sure, totally.

Which would let you delete yourself.

That only makes sense of the model is itself a Maybe at its root node, which for many things doesn't even make sense. I guess you could try to structure models to be composable, where that might make sense. But I have no idea how you could split models into sub-components using Elm. Absolutely none.

@sdegutis
Copy link
Author

But I have no idea how you could split models into sub-components using Elm. Absolutely none.

That was because I hadn't read your tutorial carefully enough. But now I have, and I do get it better. Well done! Nice tutorial!

@srobertson
Copy link

I'd love to see a working example of using this generalized version of update .

I'm trying to make an Effect that fetches some JSON via a port as a work around until Elm 0.15 comes out. But struggling a bit.

@srobertson
Copy link

Here's my first attempt

https://gist.github.com/srobertson/3c1f2ad09d50cc054297

@TheSeamau5
Copy link

I have used this archtecture a few times now and I've realized that I often have NoOp in my actions. To distinguish them I give them different names: NoClick, NoChange, NoMove, etc...

So, I kinda switched from dealing with Action to Maybe Action as it is more general and allows me to avoid having all of these NoOp thingies.

So, as such, I think that the general case would be :

update : UpdateContext -> Maybe Action -> Model -> (Model, Effect)

And, I don't know about the deleting oneself. I think that intent should be passed in through the Effect type and the parent is the one who decides. It kinda helps make things more general because you might just have a button and it so happens that this button is shaped like an X and deletes itself but it's just a button and should only communicate that it got clicked in some sense.

@evancz
Copy link
Owner

evancz commented Aug 12, 2015

Alright, examples 5 through 8 should give a more comprehensive answer to this question now. If you want to do custom effects that handle GraphQL and the like, you can make a graphql-effects that is based on the elm-effects package as a basic foundation.

@evancz evancz closed this as completed Aug 12, 2015
zzantares added a commit to zzantares/elm-kata that referenced this issue Jun 22, 2017
jaryncolbert added a commit to jaryncolbert/elm-architecture-tutorial that referenced this issue Mar 11, 2019
jaryncolbert added a commit to jaryncolbert/elm-architecture-tutorial that referenced this issue Mar 11, 2019
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

4 participants