[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