Koen Classen explained how to do without existantials like this:

>   class Item i where
>     foo  :: i -> Int
>     step :: i -> i
[...]
>   data ITEM = MkItem { nStepsThenFoo :: [Int] }
> 
> And a helper function:
> 
>   mkItem :: Item i => i -> ITEM
>   mkItem i = MkItem { nStepsThenFoo = map foo (iterate step i) }

instaed of

>  | > data ITEM = forall i . Item i => MkItem i

and says that

> I have applied this method several times when I thought I needed
> existential types, but I didn't need them at all. I think this might be
> the case more often.

I believe it is always possible, but it soon gets unmanagable.
If class Item contained one more member
     step' :: i -> i
you would already have to define a tree of extractable values. 
And if there are functions with types like i->i->i or i->[i], it gets
really weird. Still I guess it should be possible...
You 'only' need a structure that reflects the ways you can build a
term of a type that does not contain the existantially qualified
type variable. (See my handwaving?)

So the moral seems to be that Koen is right in his introduction where
he says:

> Don't get me wrong, I think existential types are very useful, but in some
> cases the answer is just around the corner in Haskell98, not needing
> exisistential types at all.


BTW: The examples here showed me that and how it is possible to
constrain existantial types. This is something I already wished, but I 
didn't know it was in hugs yet.

Christian Sievers



Reply via email to