
On Jun 29, 2007, at 10:07 AM, Nicolas Frisby wrote:
I wrote a combination reader/writer monad (a la the RWS monad in the mtl) and I find myself wanting to use multiple instances of it in the same stack of transformers. The functional dependencies prevent this from working out.
I found myself in a situation implementing two very similar algorithms where I had to really puzzle out how to get functional dependencies to work, and I ended up writing a class (I abridge):
class (Num b, Real c) => Elem a b c | a -> b, a -> c where qr :: a -> b -> b -> QR c
and then declaring instances like
data Rlist a = Rlist instance Integral a => Elem (Rlist a) a (Ratio a) where qr w x y = Yes (x % y) False
When I wanted this version of qr, I'd call "qr Rlist". Rlist is a dummy class parameter to get the functional dependencies to work, it does nothing besides select a version of my code. I couldn't get the functional dependencies to work out any other way, so I accepted this. Later, I realized that Haskell had named records, and I went back and rewrote stuff as follows:
data (Num b, Real c) => Elem b c = Elem { qr :: b -> b -> Rem c }
rlist :: Integral a => Elem a (Ratio a) rlist = Elem { qr = (\x y -> Just (x % y, False)) }
Now all I had to do was change the case from "qr Rlist" to "qr rlist" and the rest of my code worked exactly as before. (I love how often this sort of thing happens in Haskell.) I went from thinking that passing around a bunch of functions was kludgey, to thinking that a beginner like me using multi-parameter type classes unnecessarily was obfuscation. In any case, it didn't matter what I thought, the code either way was virtually identical. I've since done some experiments with Template Haskell, and I see that Arie Peterson has suggested how you could proceed. However, are you sure that you can't find a way to get this to work in vanilla Haskell without extensions? Or, for that matter, are you sure there isn't a way to get functional dependencies to work? (I felt pretty dumb for a little while before I found one for my problem, although as usual the issues are clear in hindsight.)