0

I have the following

data Expr = Condition v
          | And Expr Expr
          | Or Expr Expr

and I am asked to consider the follow untyped version in order to complete:

data Expr e where

I'm not sure what I'm suppose to write for the constructors. I tried the following:

data Expr e where
  Condition :: v -> Expr v
  And :: -- really not sure what to do with this one
  OR :: Expr b -> (Expr b -> Expr a) -> Maybe Expr a -> Expr b

Also, since v can be of any type ie int, bool etc is it possible just to call it the following (above) and declare the type of v later?

data v = IntVat int

any help would be much appreciated :)

EDIT : changed the whole post to add a little bit more information and clarity (based on my understanding of the exercise).

Basically I need help figuring out the constructors for the GADTs given the data Expr = Condition v...etc as reference.

Mat
  • 202,337
  • 40
  • 393
  • 406
SNpn
  • 2,157
  • 8
  • 36
  • 53
  • The non-GADT declaration of `Expr` has no parameter (in contrast to the GADT one), is that on purpose? – huon Apr 26 '12 at 08:56
  • @dbaupp I'd say so, since that was what was given to me for the exercise. – SNpn Apr 26 '12 at 08:58
  • `V` is not a type variable (in the first definition), since it's uppercase it must refer to a specific type, right? – Peter Apr 26 '12 at 09:00
  • @Peter oh sorry, its lower case – SNpn Apr 26 '12 at 09:05
  • 1
    Shouldn't your first code be 'data Expr v = Condition v | And (Expr v) (Expr v) | Or (Expr v) (Expr v)'? – gfour Apr 26 '12 at 09:32
  • @gfour as I said above, I was given the untyped `Exer` – SNpn Apr 26 '12 at 10:08
  • But it is not valid Haskell, GHC/GHCi will not compile this code, so its semantics is not well-defined. Where does 'v' come from? Is it an existential (as phg proposes below), or a type variable (that should be written the proper Haskell way)? – gfour Apr 26 '12 at 11:55
  • I do not quite understand what the problem is that you are asked to solve. Could you give us a bit more information about the exercise? – Stefan Holdermans Apr 26 '12 at 12:06
  • @gfour i've edited the OP, hope that helps – SNpn Apr 26 '12 at 14:29
  • 'data v = IntVat int': Data type names in Haskell start with a capital letter (only variables start with a lowercase letter). This means that 'int' should be 'Int' and 'v' should be 'V'. If I understand correctly, you try to leave a "hole" with 'v' in your previous definition and define here 'data v = ...' to fill it, but Haskell does not work this way. – gfour Apr 26 '12 at 14:44

2 Answers2

3

If I were setting an assignment on GADTs using a basic expression language as the motivating example, here's the kind of answer I'd have in mind:

data Expr v where
    Literal :: v -> Expr v
    And     :: Expr Bool -> Expr Bool -> Expr Bool
    Or      :: Expr Bool -> Expr Bool -> Expr Bool
    -- and I'd probably add some things like this to
    -- show why the type variable is useful
    Equal   :: Expr Int -> Expr Int -> Expr Bool
    If      :: Expr Bool -> Expr v -> Expr v -> Expr v

You can see why you might call this a "typed" expression: the instantiations of the type variables look like typing rules for a small language:

a : Bool         b : Bool
-------------------------
    And a b : Bool

a : Int          b : Int
------------------------
    Equal a b : Bool

etc.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
0

That sounds like an existential type to me. I must admit, I've never really used them, I only tried to understand them; anyway, maybe it's meant like this:

data Expr = forall v. Condition v
          | And Expr Expr
          | Or Expr Expr

Then you had a GADT like this (they generalize existentials, see here):

data Expr where
    Condition :: v -> Expr
    And :: Expr -> Expr -> Expr
    Or :: Expr -> Expr -> Expr

Although, that wouldn't (as far as I understood the concept) make much sense, since you can't use v for anything.

On the other hand, this would (I hope) make more sense (since there's a "condition"):

class Testable v where
    test :: v -> Bool

data Expr where
    Condition :: Testable v => v -> Expr
    And :: Expr -> Expr -> Expr
    Or :: Expr -> Expr -> Expr

then you could do, e.g.

eval :: Expr -> Bool
eval (Condition v) = test v
eval (And e1 e2) = (eval e1) && (eval e2)
eval (Or e1 e2) = (eval e1) || (eval e2)

which would work for different kinds of "conditions".

I didn't test this code, though, and, as I've said, I'm not really a professional about existentials. I hope my code is correct, but please tell me anyone, if you know better (or I'm totally wrong...)

phipsgabler
  • 20,535
  • 4
  • 40
  • 60
  • `data Expr` is an untyped version of the `Expr` – SNpn Apr 26 '12 at 10:04
  • `Expr` as existential (with the forall) is "untyped", too, in the sense that it has kind `*`. However, it can store different types, which are later accessible by pattern matching the constructor. Also, I agree with gfour, that leaving those `v`s probably was a mistake. Adding them would lead to a normal, tree-like recursive type. – phipsgabler Apr 26 '12 at 10:38