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