Thanks Simon! Wool looks quite interesting, and I haven't heard of it before. At first glance it reminds me a bit of Adam Dunkel's protothreads (from the sensor network world), which may be no coincidence since they're at the same institution:
http://www.sics.se/~adam/pt/
My ultimate goal is an "abstract-deque" parameterizable interface that abstracts over bounded/unbounded, concurrent/non-concurrent, single, 1.5, and double-ended queues, which would include both, say, Michael & Scott linked queues and the Chase-Lev work-stealing deques. An aggregated queue package could use type families to dispatch to the best available queue implementation for a given configuration.
I've got a couple drafts of how this might work. They're in different branches here:
One of them uses an associated data type family, the other an unassociated one. The type family has a bunch (six) phantom type parameters, and the unassociated one allows hiding those parameters at the expense of introducing more type classes.
MegaQueue.hs will be used to aggregate together different queue implementations. The end result is that someone can create a new queue by setting all the switches on the type, as follows:
test = do
q :: Deque NT T SingleEnd SingleEnd Bound Safe Int <- newQ
pushL q 33
x <- tryPopR q
print x
return q
With those settings, requiring only single-ended rather than double-ended queues, the above code can use the LinkedQueue (Michael and Scott) implementation included in that repo.
That little test, by the way, segfaults for me on Mac OS under GHC 7.2.1 even WITHOUT using casMutVar# (It's using Data.CAS.Fake presently.) I'll file a bug report after I sanity check it some more.
Disregarding that... the big problem in this case is the inability to create overlapping type family instances.
In this case what we dearly WANT to do is specialize some subset of the 64-mode configuration space and then have a "fallback". You can take a look at my struggling in MegaDeque. Both of my approaches require specifying explicitly the modes that you don't cover.
Worse, we may want to specialize on element type as well. For example, for simple scalar types (or even Storable types) it may be desirable to use something foreign, like TBB queues. But in that case, there's no way to enumerate the types NOT specialized. As far as I know there is no way for type families to accomplish this (specialize, say "Int", and have a fallback for everything else). In general, is there a recognized work-around for this? For example, is this a place where using functional dependencies instead might do the trick?
Also, there are some software-engineering issues here with respect to where to put the instances. It would be nice to put the instances for DequeClass inside the individual implementations (like LinkedQueue.hs). But that leads to problems because it's really the job of MegaQueue.hs to figure out how to spread implementations over the configuration-space. And once you put the instances in LinkedQueue.hs there is of course no way to qualify or hide them upon import....
Feedback welcome.
Cheers,
-Ryan