Hello!

I have a problem with overlapping instances for which I already know a workaround. However, I'm still curious to know if there isn't a simpler solution available. I have a feeling that -fallow-incoherent-instances might be the answer, but I can't get it to work.

In the code at the end of the message, (Block w n s e) is a representation of a geometrical block whose west-/north-/south-/eastern edge has type w/n/s/e respectively. (*||*) composes two blocks horizontally and (*=*) composes vertically. In this simplified example, there is only one primitive block -- unitBlock.

Now, I want to be able to make grids of unitBlock:s where the edges can have any type that can be obtained using (,) and (). This is what the Grid class attempts.

The program compiles fine until I add the test program

test :: Block ((),()) ((),()) ((),()) ((),())
test = grid

which raises an "Overlapping instances" error. What I would like is for the compiler to pick *either* of the two matching instances first, and then the other one, because in this particular case, it doesn't matter which one it picks first.

The workaround is to explicitly pick an order by giving the additional instance (requires -fallow-overlapping-instances):

instance ( Grid x1 y1
         , Grid x1 y2
         , Grid x2 y1
         , Grid x2 y2
         ) => Grid (x1,x2) (y1,y2)
  where
    grid = grid *||* grid

Is there any way to make this work without adding this last instance?

Thanks!

/ Emil



--------------------------------------------------------

data Block w n s e = Block

(*||*) :: Block w1 n1 s1 x -> Block x n2 s2 e2 -> Block w1 (n1,n2) (s1,s2) e2
(*||*) = undefined

(*=*) :: Block w1 x s1 e1 -> Block w2 n2 x e2 -> Block (w1,w2) n2 s1 (e1,e2)
(*=*) = undefined

unitBlock :: Block () () () ()
unitBlock = undefined

class Grid x y
  where
    grid :: Block x y y x

instance Grid () ()
  where
    grid = unitBlock

instance (Grid x1 y, Grid x2 y) => Grid (x1,x2) y
  where
    grid = grid *=* grid

instance (Grid x y1, Grid x y2) => Grid x (y1,y2)
  where
    grid = grid *||* grid


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to