Every week one of the founders of my company sends around a miscellaneous question, and collates the answers, which are shared with everyone on Monday. This week the question was “What's the best advice you've ever heard?”
My first draft went like this:
When I was a freshman in college, I skipped a bunch of physics labs that were part of my physics grade. Toward the end of the semester, with grades looming, I began to regret this and went to the TA, to ask if I could do them anyway. He took me to see the lab director, whose permission was required.
The lab director asked why I'd missed the labs the first time around. I said, truthfully, that I had no good excuse.
As soon as the I had left the room with the TA, he turned to me and whispered fiercely “You should have lied!”
That advice is probably very good, and I am very bad at taking it. I should have written a heartwarming little homily about how my uncle always told me always to always look for the good in people's hearts, or something uplifting like that.
So here I am, not taking that TA's advice, again.
I thought about that for a while and wondered if I could think of anything else to write down. I added:
If you don't like “You should have lied!”, I offer instead “Nothing is often a good thing to do, and always a clever thing to say.”
I thought about that for a while and decided that nothing was a much cleverer thing to say, and I had better take my own advice. So I scrubbed it all out.
I did finally find a good answer. I told everyone that when I was fifteen, my cousin Alex, who is a chemistry professor, told me never to go anywhere without a pen and paper. That may actually be the best advice I have ever received, and I do think it beats out the TA's.
This is the first real release shapely-data, a haskell library up here on hackage for working with algebraic datatypes in a simple generic form made up of haskell’s primitive product, sum and unit types: (,), Either, and ().
You can install it withcabal install shapely-data Motivation and examples
In order from most to least important to me, here are the concerns that motivated the library:
Provide a good story for (,)/Either as a lingua franca generic representation that other library writers can use without dependencies, encouraging abstractions in terms of products and sums (motivated specifically by my work on simple-actors.
Support algebraic operations on ADTs, making types composable-- multiplication: let a = (X,(X,(X,()))) b = Left (Y,(Y,())) :: Either (Y,(Y,())) (Z,()) ab = a >*< b in ab == ( Left (X,(X,(X,(Y,(Y,()))))) :: Either (X,(X,(X,(Y,(Y,()))))) (X,(X,(X,(Z,())))) ) -- exponents, etc: fanout (head,(tail,(Prelude.length,()))) [1..3] == (1,([2,3],(3,()))) (unfanin (_4 `ary` (shiftl . Sh.reverse)) 1 2 3 4) == (3,(2,(1,(4,()))))
Support powerful, typed conversions between Shapely typesdata F1 = F1 (Maybe F1) (Maybe [Int]) deriving Eq data F2 = F2 (Maybe F2) (Maybe [Int]) deriving Eq f2 :: F2 f2 = coerce (F1 Nothing $ Just [1..3]) data Tsil a = Snoc (Tsil a) a | Lin deriving Eq truth = massage "123" == Snoc (Snoc (Snoc Lin '3') '2') '1'
Lowest on the list is supporting abstracting over different recursion schemes or supporting generic traversals and folds, though some basic support is planned.
Finally, in at least some cases this can completely replace GHC.Generics and may be a bit simpler. See examples/Generics.hs for an example of the GHC.Generics wiki example ported to shapely-data. And for a nice view on the changes that were required, do:git show 3a65e95 | perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight Why not GHC.Generics?
The GHC.Generics representation has a lot of metadata and a complex structure that can be useful in deriving default instances; more important to us is to have a simple, canonical representation such that two types that differ only in constructor names can be expected to have identical generic representations.
This supports APIs that are type-agnostic (e.g. a database library that returns a generic Product, convertible later with to), and allows us to define algebraic operations and composition & conversion functions.