[Haskell-cafe] Pulling an applicative/apply out of a record
Tyson Whitehead
twhitehead at gmail.com
Sun Feb 7 07:25:41 UTC 2016
Quick question for the experts out there.
I need to process some records. The records come in in an unordered stream of record fields. From each stream of fields I want to produce a Record entry containing the fields I need to do my calculation.
> data Record = { field1 :: Type1, field2 :: Type2, ... }
I was thinking this setup might work nice with something like
> data RecordF d = RecordF { field1 :: f Type1, field2 :: f Type2, ... }
as I could then have (1) a monoid version I could accumulate use as an accumulator over the stream
> type RecordM = RecordF []
and (2) a final version.
> type Record = RecordF Identity
This final version seems like it should easily come from the later by pulling the [] (or anything else that has the Apply/Applicative structure) to the outside and then taking the head of the resulting list.
While I could write the boilerplate to do this, it seems like something I should be able to do more elegantly. The best I have come up with so far is to use the lens package to give me an isomorphism to a tuple. Then I need a uncurried zip for arbitrarily large tuples. Follow this by an isomorphism back.
RecordF (f Type1) (f Type2) ... -> (f Type1, f Type2, ....)
-> f (Type1, Type2, ...) -> f (Record Type1 Type2 ...)
I can't seem to find any uncurried zip implementations for arbitrarily large tuples (or any other way to do this without writing the boilerplate). Am I missing something? Is there a better way to do this?
Thanks! -Tyson
PS: It seems the Data.Vinyl package has something along these lines with the rtraverse function
https://hackage.haskell.org/package/vinyl-0.5.1/docs/Data-Vinyl-Core.html
More information about the Haskell-Cafe
mailing list