Chcę zdefiniować klasę typów dla obiektów geometrycznych, które można przecinać razem:
class Intersect a b c | a b -> c where
intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies
Chodzi o to, aby mieć funkcje przecięcia ogólnego przeznaczenia, które mogą obsługiwać obiekty różnych typów. Można sobie wyobrazić takie przypadki jak
instance Intersect Line Plane (Maybe Point) where
...
instance Intersect Plane Plane (Maybe Line) where
...
Ale chcę również zadeklarować, że skrzyżowanie jest przemienne:
instance (Intersect a b c) => Intersect b a c where
intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances
Problem polega na tym, że ilekroć oceniam intersect x ybez uprzedniego zdefiniowania wystąpienia formy Intersect a b c, gdzie ajest typ xi bjest typ y, program przechodzi w nieskończoną pętlę , prawdopodobnie spowodowaną deklaracją instancji rekurencyjnej o komutatywności. Idealnie intersect Egg Baconbyłoby, gdyby coś takiego nie sprawdziło się podczas sprawdzania typu, ponieważ nie zdefiniowano takiej instancji, aby nie uwięzić mnie w nieskończonej pętli. Jak mogę to zaimplementować?