[Haskell-cafe] Type-level programming problem

Thomas Schilling nominolo at googlemail.com
Mon Apr 30 12:01:35 EDT 2007


I have a type class similar to this one.

data T
class Foo ns a b c | ns -> a, ns -> b, ns -> c where
     mkFoo :: ns
     defaultA :: a
     defaultB :: c -> IO b
     defaultC :: [T] -> c
     f :: c -> b -> a -> (b, Int)

The idea is, that I define classes of components where the data types  
of the methods are component-specific.  I therefore use a namespace  
to define the component types (associated types would be nicer, but  
are not widely supported).

Given a few sample instances, I can define a configuration:

data X;  data XA = XA;  data XB = XB;  data XC = XC

instance Foo X XA XB XC where
     mkFoo = undefined
     defaultA    = XA
     defaultB XC = return XB
     defaultC _  = XC
     f _ b _ = (b,0)
mkX = mkFoo :: X

data Y;  data YA = YA;  data YB = YB;  data YC = YC

instance Foo Y YA YB YC where
     mkFoo = undefined
     defaultA    = YA
     defaultB YC = return YB
     defaultC _  = YC
     f _ b _ = (b,1)
mkY = mkFoo :: Y

config = mkX .*. mkY .*. HNil

Using this configuration, I now want to define various functions that  
work on As, Bs or Cs, respectively.  For example, I'd like to have

a :: XA :*: XB :*: HNil
a = hMap DefaultA config

but I fail to figure out how to define DefaultA.  I tried with this one:

data DefaultA
instance Foo ns a b c => Apply DefaultA ns a where
     apply _ _ = defaultA

but I get:

     Could not deduce (Foo ns1 a b1 c1)
       from the context (Apply MakeAs ns a, Foo ns a b c)
       arising from use of `defaultA'
       at /Users/nominolo/Devel/Haskell/testcase1.hs:126:16-23
     Possible fix:
       add (Foo ns1 a b1 c1) to the class or instance method `apply'
     In the expression: defaultA
     In the definition of `apply': apply _ _ = defaultA
     In the definition for method `apply'

I guess I need some type class that also binds b and c.  Or maybe I  
need to do some things completely different at all.  Ideally, I'd  
hope to keep the work for adding new Foo instances as low as  
possible, though.

I attached the relevant parts of the HList implementation and the code.

Any suggestions?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: testcase1.hs
Type: application/octet-stream
Size: 2366 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20070430/0eed72e2/testcase1.obj

More information about the Haskell-Cafe mailing list