Pedro Fernandes
Pedro Fernandes

Reputation: 198

How to go from tuples to a custom data type?

So, I'm having this class about catamorphisms and what not, and I need to code the in of a data type.

The data type is

data Expr = Num Int | Bop Expr Op Expr  deriving  (Eq,Show)

and the function must have this signature

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr

inExpr should be, I think, something along the lines of

inExpr = Either Num (Bop something)

but I can't figure out the something.

Upvotes: 2

Views: 155

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477616

You are quite close. We can in fact easily derive the type of something by using a "hole" (_) in ghci:

Prelude Data.Either> :{
Prelude Data.Either| inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
Prelude Data.Either| inExpr = either Num _
Prelude Data.Either| :}
<interactive>:36:21: error:
    • Found hole: _ :: (Op, (Expr, Expr)) -> Expr
    • In the second argument of ‘either’, namely ‘_’
      In the expression: either Num _
      In an equation for ‘inExpr’: inExpr = either Num _
    • Relevant bindings include
        inExpr :: Either Int (Op, (Expr, Expr)) -> Expr
          (bound at <interactive>:36:1)

So we know that this function _ will need to have as type (Op, (Expr, Expr)) -> Expr.

We can for example use a lambda-expression here:

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
inExpr = either Num (\(o, (l, r)) -> Bop l o r)

We thus "unpack" the tuple and the subtuple with a (o, (l, r)) pattern, and then construct an Expr by using the Bop data constructor, with l, o and r as arguments.

That being said, simple pattern matching, for example in the head of the fucntion, will do the trick as well, and is perhaps easier to understand:

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
inExpr (Left a) = Num a
inExpr (Right (o, (l, r))) = Bop l o r

Upvotes: 6

radrow
radrow

Reputation: 7159

Why don't just

inExpr ie = case ie of
  Left n -> Num n
  Right (o, (e1, e2)) -> Bop e1 o e2

?

Or if you like either function

inExpr = either Num (\(o, (e1, e2)) -> Bop e1 o e2)

Upvotes: 9

Related Questions