-
Notifications
You must be signed in to change notification settings - Fork 17
Added appendRecord, works on two records containing semigroups #5
base: master
Are you sure you want to change the base?
Conversation
Different rows? Like if there are keys missing from one or the other? Not sure if there's a easy way to do that without some kind of overloaded instances... |
…irst one (thanks to @MonoidMusician and @paluh), added memptyRecord
@justinwoo so, after some help and discussion from @MonoidMusician and other people on #purescript channel on slack (mostly @paluh), I have decided to not do full outer-join append. Instead,
will result in
Then I have added
What do you think? My use-case probably would be in frontend architectures like purescript-pux, where you have a single state type and then you update it based on incoming events. |
I'm kind of working on an Entity Component System based on similar ideas. At initialization the user provides an RProxy specifying the set of all components that can be stored and the ECS creates an isomorphic record of, say, empty IntMap's, one for each component with the appropriate element type. Then each entity will have associated with its ID only a subset of those components with values stored in the corresponding storages. Each system consists of a function from one RProxy to another, with each of those containing only some subset of possible components. When the user wants to map a system over components, we collect the IntMaps associated with the rows present in the system's input Record type, intersect their key sets to know which entity ID's to operate on, and end up doing inserts into the storage rows specified in the system's output type. I'm expecting to run into some showstopper along the way, but you're showing me this is closer to possible than I first thought. A stretch goal would be for the library to do automatic loop fusion, where if you're mapping two systems in sequence that use mostly the same rows, the ECS can "transpose" your strategy and do them both in one pass over the component storages. Having the whole structure represented at the type level means everything can be inlined, CSE's between the two systems can be optimized away, etc. |
@Gerstacker if I understand correctly, there should be lot of changes coming in this regard with the purescript 0.12 release, where we might start seeing some proper type-classes for records showing up. I.e. maybe even proper Eq, e.t.c. Currently there is little support for i.e. working with nested records with this stuff, but you could work around that easily by using new-types a.f.a.i.k. On the other hand, what I couldn't really figure out is how to create a union with these, but it doesn't seem that you would need it. It seems to be fairly simple to iterate over a single row-list and then build-up another 😄 You might want to check-out https://github.com/LiamGoodacre/purescript-record-apply as well, I thing there is a blog-post about it, might make more things easier? In any-case, if I were you, I would try to make a prototype, and then complain on #purescript slack channel if it doesn't work. So far, somebody has always helped me with my weird questions 😃. |
Hi @AdamSaleh, I hope it's ok to ask this here... |
Hi @Gerstacker, the rule for using This is documented somewhere, I don’t remember where off the top of my head. |
Thanks @MonoidMusician, this does have something to do with it. I already had functional dependencies in both directions between this row type variable and a RowList type variable. What got rid of the "Type class instance head is invalid due to use of type" error was removing the FD from the row to the Row Type (keeping the one that determines the Row kind parameter as you suggest). There's now a compiler error elsewhere that I don't think is related. |
Regarding mempty and append implementations (and maybe other typeclasses methods from this lib) - maybe it is worth to provide a newtype wrapper for record: newtype Record' r = Record' (Record r) to have instance semigroupRecord' ∷ (RowToList r rl, AppendSubrecordImpl rl r r) ⇒ Semigroup (Record' r) where
append (Record' r1) (Record' r2) = Record' $ appendRecord r1 r2 |
Hey @AdamSaleh and @MonoidMusician and @justinwoo |
Hi,
I created another one of these. Currently takes two records of the same row-type and creates a new record with the values appended with
<>
. Works on non-homogenous records, i.e:will result in
Do you think it would be a good idea to make this work for two records with different rows? I am not sure how would I do that yet :-)