
On Mon, Feb 28, 2011 at 12:41 PM, wren ng thornton
On 2/28/11 2:43 AM, Yitzchak Gale wrote:
You have written a large software system in Haskell. Wishing to play to Haskell's strength, you have structured your system as a series of composable layers. So you have data types
Layer1, Layer2, ...
and functions
layer2 :: Layer1 -> Layer2 layer3 :: Layer2 -> Layer3 ...
etc.
Assuming you actually name them Layer1, Layer2, etc, or use any other regular naming scheme, you can break apart the names and use typeclasses to help out:
type family Layer :: * -> * data Z data S n
class Layerable n where layer :: Layer n -> Layer (S n)
Then it's just a matter of getting the right number of them, a la lifting through monad transformer stacks. Of course, from here it's not that hard to add in some type hackery to do the lifting for you, a la "Data types a la Carte"[1]. It's not the cleanest thing ---there's a good deal of boilerplate up front--- but once it's set up, it should Just Work(tm).
I was thinking something like: class IsNat n => LayerID n where data Layer n :: * runLayer :: LayerID (S n) => Layer n -> Layer (S n) serialize :: Layer n -> L.ByteString deserialize :: L.ByteString -> Layer n and then use a reifyIntegral-esque function (a la the reflection and type-level packages) to reify two numbers up to the type level and run all of the runLayers in between the two, but where I ran into trouble was that there's no guarantee of there being a LayerID instance for any given n; and at that point you either need the non-existent 'do-this-if-there's-an-instance-and-do-that-otherwise' construction, or perhaps you can hack something with OverlappingInstances which moves the whole thing from sophisticated-but-clean-oleggery to kind of ugly. Is there any cleaner way around this?
[1] http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf
-- Live well, ~wren
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Work is punishment for failing to procrastinate effectively.