News for hackers. Stuff that matters.
Re:Class Hierarchies? Don't Do That by tel on Sunday March 30, 2014 @06:22PM (#7498221)
I mean, I agree such examples exist. I don't think this is yet a truly good example, though. The real advantage to existential types like this are in creation of multiple variants---again I recommend reading Jeremy Gibbons' paper.

But, for completeness, here's how you could write your type

    {-# LANGUAGE ExistentialQuantification #-}
    data Test = forall i o . Test i (i -> o) (o -> o -> Bool) o
Although, note, this is exactly equivalent to `Bool`, although in two ways—if we knew the comparator function was commutative then there'd be just one way to convert to `Bool`.

    testBool :: Test -> Bool
    testBool (Test i fun cmp o) = cmp (fun i) o

    testBool' :: Test -> Bool
    testBool' (Test i fun cmp o) = cmp o (fun i)
But in either case there are no other ways to "observe" the existentially quantified types since we've forgotten absolutely everything besides `Bool`. More likely we would want to also, say, show the input.

    data Test = forall i o . (Eq o, Show i) =>
                Test i (i -> o) o
and this type is now equal to `(String, Bool)`.

    testOff :: Test -> (String, Bool)
    testOff (Test i fun o) = (show i, fun i == o)
So, in general, if you're using existential types you really want to either be using multiple variants or when you have such a combination of observables that it's not worth expressing them all directly.

There are no comments on this comment yet.