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 y
bez uprzedniego zdefiniowania wystąpienia formy Intersect a b c
, gdzie a
jest typ x
i b
jest typ y
, program przechodzi w nieskończoną pętlę , prawdopodobnie spowodowaną deklaracją instancji rekurencyjnej o komutatywności. Idealnie intersect Egg Bacon
był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ć?