[clean-list] Existential Types

Jay Kint jean-luc-picard@ussenterprise.com
Mon, 22 Oct 2001 01:23:33 -0600


This question probably comes up, but I think this is very much the "pointer"
question of Clean.  Why doesn't the following compile?

:: Surface = E.s:  {
     state :: s,
     intersect :: (Ray s -> (Bool, Real)),
     colorSurface :: Ray s -> Color
     }

Intersect :: Ray [Surface] -> (Bool, Real, Surface)

... somewhere in a function definition ...
where
   ( found, d, surface=:{state, colorSurface} ) =
        Intersect r surfs
   c :: Color
   c
    | found == True = colorSurface r state
    | otherwise  = { Color | r = 0.0, g = 0.0, b = 0.0 }
   r :: Ray
   r = { Ray | origin = { x = toReal x, y = toReal y, z = 0.0 }, direction =
{ x = 0.0, y = 0.0, z = -1.0 }}
   ColorSurface :: Ray Surface -> Color
   ColorSurface r { state, colorSurface } = colorSurface r state

As perhaps you have guessed from this snippet, I am writing an elementary
ray tracer in Clean.  It is my pet project I do to learn a new language, and
in this case I'm trying to duplicate the ICFP 2000 contest as well.

The clincher is this.  I have an intersection function that returns the
"surface", as you can see, an existential type.  It then wants to calculate
the color of the pixel there.  To do this, I have a colorSurface member of
the surface record that is, as you can guess, designed to calculate it based
on the shape type (Sphere, Triangle, and Plane for now)

I also have a helper function ColorSurface, that seems to solve this problem
for me (which I have yet to fully elaborate), if I put in "ColorSurface r
surface" in place of "colorSurface r state"

Here's the question.  Why is the ColorSurface function necessary when all it
does forward the function call to colorSurface?  The parameter pattern
{state, colorSurface} seems to do some sort of type binding/checking that
the "(found, d, surface=:{state, colorSurface}) = Intersect r surfs" doesn't
do.  Is this correct, and if so, why can't the second expression do the same
type checking?

The compilation error I get is "Type error [RayTracer.icl,222,OutputColor]:
existential type variable cannot be instantiated due to internal argument
colorSurface of c"

I'm baffled.

Jay