type signatures with existentially quantified data constructors

Dylan Thurston dpt@math.harvard.edu
Thu, 16 Aug 2001 14:40:37 -0400


On Thu, Aug 16, 2001 at 01:11:25AM -0400, Avi Pfeffer wrote:
> Works fine.  Things get tricky when I try to add pairs.  In order to type
> a pair expression, I find I need to create a Pair class and introduce a 
> class constraint:
> 
> class Pair a b c | a -> b c, b c -> a 
>
> instance Pair (b,c) b c 

I tried making this:

class Pair a b c | a -> b c, b c -> a where
  mkPair :: b -> c -> a
  breakPair :: a -> (b, c)

instance Pair (b,c) b c where
  mkPair    = (,)
  breakPair = id

so that then you can do...

> data Expr a = ... | forall b c . Pair a b c => MkPair (Expr b) (Expr c)
> 
> This seems to express the right type relationships.  But now I find I
> can't write eval for MkPair:
> 
> eval (MkPair x y) = (eval x, eval y)

eval (MkPair x y) = mkPair (eval x) (eval y)

But this didn't work either.  I agree that it should.

As an alternative, you could make Expr into a class rather than a data
constructor, like this:

----
class Expr a b | a -> b where
  eval :: a -> b

data Haskell a = Haskell a
instance Expr (Haskell a) a where
  eval (Haskell x) = x

data If a = forall x y z . (Expr x Bool, Expr y a, Expr z a) => If x y z
instance Expr (If a) a where
  eval (If x y z) = if eval x then eval y else eval z

data Appl a = forall x y b . (Expr x (b -> a), Expr y b) => Appl x y
instance Expr (Appl a) a where
  eval (Appl x y) = eval x (eval y)

data MkPair a b = forall x y . (Expr x a, Expr y b) => MkPair x y
instance Expr (MkPair a b) (a,b) where
  eval (MkPair a b) = (eval a, eval b)
----

Best,
	Dylan Thurston