Quiero definir una clase de tipo para objetos geométricos que se puedan intersectar juntos:
class Intersect a b c | a b -> c where
intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies
La idea es tener funciones de intersección de propósito general que puedan manejar objetos de diferentes tipos. Uno podría imaginarse instancias como
instance Intersect Line Plane (Maybe Point) where
...
instance Intersect Plane Plane (Maybe Line) where
...
Pero también quiero declarar que la intersección es conmutativa:
instance (Intersect a b c) => Intersect b a c where
intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances
El problema es que cada vez que evalúo intersect x y
sin definir primero una instancia de la forma Intersect a b c
, donde a
es el tipo de x
y b
es el tipo de y
, el programa entra en un bucle infinito , presumiblemente causado por una declaración de instancia recursiva sobre la conmutatividad. Idealmente, quiero que algo como intersect Egg Bacon
no verificar el tipo porque no se definió tal instancia, no atraparme en un bucle infinito. ¿Cómo puedo implementar esto?
fuente
Respuestas:
Primero, puede usar el paquete conmutativo , en cuyo caso modificaría la firma de tipo de
intersect
lo siguiente, pero de lo contrario el resto de su código "simplemente funcionaría":Sin embargo, también puede usar QuickCheck con hspec para ejecutar una prueba de propiedad en todas las instancias de su clase de tipos para asegurarse de que realmente viaje. Esto puede reducir los gastos generales: tendrías que hacer un punto de referencia ya que no lo sé. Por ejemplo:
fuente