Voglio definire una classe di tipi per oggetti geometrici che possono essere intersecati insieme:
class Intersect a b c | a b -> c where
intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies
L'idea è di avere funzioni di intersezione generiche in grado di gestire oggetti di diverso tipo. Si potrebbero immaginare casi come
instance Intersect Line Plane (Maybe Point) where
...
instance Intersect Plane Plane (Maybe Line) where
...
Ma voglio anche dichiarare che l'intersezione è commutativa:
instance (Intersect a b c) => Intersect b a c where
intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances
Il problema è che ogni volta che valuto intersect x y
senza prima definire un'istanza della forma Intersect a b c
, dove a
è il tipo di x
e b
è il tipo di y
, il programma entra in un ciclo infinito , presumibilmente causato dalla dichiarazione di istanza ricorsiva sulla commutatività. Idealmente voglio qualcosa come intersect Egg Bacon
per fallire nel controllo del tipo perché non è stata definita alcuna istanza, non mi ha intrappolato in un ciclo infinito. Come posso implementarlo?