Estoy tratando de escribir un rastreador de rayos simple en Haskell. Quería definir una clase de tipos que representan los diferentes tipos de superficies disponibles, con una función para determinar donde un rayo de ellos se cruza:Variable de tipo ambiguo 'blah' en la restricción ... ¿cómo solucionarlo?
{-# LANGUAGE RankNTypes #-}
data Vector = Vector Double Double Double
data Ray = Ray Vector Vector
class Surface s where
intersections :: s -> Ray -> [Vector]
-- Obviously there would be some concrete surface implementations here...
data Renderable = Renderable
{ surface :: (Surface s) => s
, otherStuff :: Int
}
getRenderableIntersections :: Renderable -> Ray -> [Vector]
getRenderableIntersections re ra = intersections (surface re) ra
Sin embargo, esto me da el error:
Ambiguous type variable 's' in the constraint:
'Surface'
arising from a use of 'surface'
(El real el código es más complejo, pero he intentado destilarlo en algo más simple, manteniendo la esencia de lo que estoy tratando de lograr).
¿Cómo puedo solucionar esto? O, como alternativa, dado que procedo de un entorno OO estándar, ¿qué estoy haciendo fundamentalmente mal?
... pero dado que todas las superficies implementan el método de 'intersecciones', ¿por qué no es suficiente? Obviamente, con mi experiencia, veo 'Surface' como una clase abstracta e 'intersections' como un método virtual. – stusmith
@stusmith: ver mi actualización. No puede tener parámetros de tipo abierto en medio de expresiones. O bien toda la expresión es paramétrica, o todos los tipos pueden determinarse estáticamente. (Tal vez hay una extensión GHC o algo que permite eso, pero no lo sé) –
¿Significa esto que Haskell no tiene el equivalente de funciones "virtuales"? Quería tener una lista de Renderables, y poder trabajar en ellos como tipos abstractos. Por lo tanto, ¿necesito tener '[Renderable s]' en su lugar? ¿Y puede esa lista contener instancias heterogéneas de 'Renderable' con diferentes instancias' Surface'? – stusmith