Every data type is going to need its own view function, right? (I am assuming your thingList corresponds to the "List data" argument to Table.view.) It seems like that would be the logical place to put the pagination logic.
Your pagination could be encapsulated by a function like "paginate : Config -> List a -> List a" that is perfectly generic and calls List.take or whatever. Each of your view functions could then call this function. Yes, the call to paginate would be duplicated in each of your view functions, but it is a better sort of duplication than, say, defining take/drop on your over-arching ThingList type and having tons of case statements. It will be easier to maintain, and easier on the eyes! In my (recent, painful) experience, Elm works much better when you focus on "vertical encapsulation" -- your main union type has a case statement in your outer "update" function, your outer "view" function, and nowhere else. What you are trying to do with your list operations, I would describe as "horizontal encapsulation" -- trying to define as many operations as possible on your main union type. If you focus on vertical encapsulation, Elm will make your life easy. If you focus on horizontal encapsulation, Elm will be your enemy every step of the way. On Mon, Aug 1, 2016 at 7:29 AM, OvermindDL1 <[email protected]> wrote: > As another way to think about this, and I am unsure how Elm'ish this is > (but it is very functional), you could invert your lists into being > functions, then pass in commands to operate on the internal lists. This is > how some functional list implementations are developed especially when > missing HKT's like Elm is (when is Elm getting HKT's anyway?). > > > On Monday, August 1, 2016 at 1:46:53 AM UTC-6, Ryan W wrote: >> >> I want to be able to store several different types of lists in a single >> data structure, and and each type of list should be treated differently by >> the view function. >> >> What I've tried: >> type ThingList >> = FooList (List Foo) >> | BarList (List Bar) >> | BazList (List Baz) >> >> >> This works okay, but if I want to do something like get the length of a >> ThingList without caring about whether it is a FooList, BarList or >> BazList it seems I have to have to write something like this: >> >> length : ThingList >> length thingList = >> case thingList of >> FooList list -> >> List.length list >> >> BarList list -> >> List.length list >> >> BazList list -> >> List.length list >> >> Since in my actual program I plan to have several more sub-types in the >> actual counterpart to ThingList this becomes somewhat cumbersome and it >> definitely isn't DRY. I guess this is a form of the expression problem? >> <https://en.wikipedia.org/wiki/Expression_problem> I tried to generalize >> it a bit so I wouldn't have to update as many of these functions when I add >> a new sub-type like this: >> reduce : (List a -> b) -> EntityList -> b >> reduce f entityList = >> case entityList of >> FooList list -> >> f list >> >> BarList list -> >> f list >> >> BazList list -> >> f list >> >> but that gave me an error like this: >> >> Function `f` is expecting the argument to be: List Foo But it is: List Bar >> >> In my particular case, at least for now, I only wanted the length of a >> ThingList literal so I can work around it, but I'm curious if there is >> way to structure the types that avoids this problem. >> >> -- > 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. > -- 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.
