Thanks for this discussion, these kinds of modelling decisions I feel like I struggle with over and over. And inevitably I get something not quite right and then later have a massive cleanup to do since everything else depends on the shape of the model :(
I like your step by step procedure Rupert, it kind of puts in words what I've been doing, but in a more systematic way. I often do end up with "a product of sums of little products", -- several things that each have distinct states, each of which have some sets of fields in common and some not. In other words an attempt to deal with Brian's "'this is like that except for...' problem ... the core software design problem in messy domains." (And let's face it, *every* domain outside of general purpose tools is 'messy'). I would like to experiment more with encapsulation via opaque types in applications, it often feels like overkill to me in applications (vs. in libraries), but would help in terms of isolating changes to the model and its core API, obviously. On Thursday, February 23, 2017 at 6:22:59 PM UTC-5, Rupert Smith wrote: > > On Thursday, February 23, 2017 at 8:57:32 PM UTC, Brian Marick wrote: >> >> The first animal is in the Compact state, the second in Expanded, and the >> last in Editable. Would you be suggesting a `Mode` like the following? >> >> type Mode >> = Compact Animal >> | Expanded Animal >> | Editable Animal FormData >> > > Yes, that is the pattern I am working with at the moment. > > >> I had problems with that. I too often had view code that had to know both >> that it was given `FormData` and also had to take the whole `Mode` as an >> argument - or had to assemble a Mode from the pieces they were given. >> (Unfortunately the details are fuzzy in my memory.) >> > > I forgot to include my help functions in the Gist. Adding them now. > https://gist.github.com/rupertlssmith/c948f304ce0a99cd7ba9d6b6a061251a > > I also have situation where I need to write a function the uses >1 of the > little products that make up a state. I wrote a mapWhenCompose function for > that. I can also tell you that my first 7 attempt to write this function > each occupied about 20 lines of code and none of them compiled! Then almost > by chance, or was it a good nights sleep, the answer came to my no longer > young and brilliant mind: > > mapWhenCompose : (c -> d -> Maybe a) -> (a -> d -> Maybe b) -> c -> d -> > Maybe b > mapWhenCompose mapWhen1 mapWhen2 func state = > mapWhen1 func state > |> andThen ((flip mapWhen2) state) > > so if you follow my pattern and write the mapWhenWithAnimal and > mapWhenWithFormData functions, then you can do: > > editableView animal formData = ... > > and then call it with: > > mapWhenCompose mapWhenWithAnimal mapWhenWithFormData editableView mode > > Note also that mapWhenCompose also returns a mapWhen function so can be > further composed. > > ==== > > What I really like about this pattern is that I have eliminated all Maybes > from my model. But now I am using Maybes to linearize the logic and to be > able to compose pieces of logic together, using Nothing to indicate a > failure of a logic flow to complete. This feels like a much better way to > use Maybes. > -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
