0

I have this simple list structure where every leaf holds two values (a and b) and every node holds one value (a)

data List a b = Leaf (a, b) | Node (a, (List a b)) deriving Show

And I have this function just returning the value of a node or the first value of a leaf

func (Leaf (a, b)) = a
func (Node (a, c)) = a

Is there a way avoid one of these pattern matches? In fact I'm working on a ternary-tree and functions which have more than one argument, so I have a lot of pattern matches which are all doing the same thing.

I thought about something like this

func (var (a, b)) = a

where var can be a leaf or a node, but this does not work.

3
  • 3
    (a, b) can be thought of as one value, actually. And the answer is, I think, no, or at least no, unless you're fine with using SYB. Commented Jan 13, 2015 at 16:26
  • As a side issue, you have more syntax than you need. you could do the equivalent structure List a b = Leaf a b | Node a (List a b) and then define the two patterns as top (Leaf a _) = a and top (Node a _) = a. Commented Jan 13, 2015 at 16:52
  • The word 'Variable' is a curse word in Haskell-Land. The word is datatype, not 'datavariable'. Commented Jan 13, 2015 at 18:51

2 Answers 2

3

If you're comfortable with it, you can refactor your type as:

data List a b = L (a, Either b (List a b)) deriving Show

Then,

func :: List a b -> a
func (L (a,_)) = a

Previous values like

Leaf (a, b)
Node (a, list)

are now written as

L (a, Left b)
L (a, Right list)

Depending on your code, this might be more convenient to use.

However, keep in mind that if you need to access the second component of the pair, you need to pattern match anyway. It is likely that your current datatype is more convenient, overall, than this alternative.

Sign up to request clarification or add additional context in comments.

Comments

0

I "solved" it by adding a help function returning the first value

gf (Leaf (a, b)) = a
gf (Node (a, b)) = a

So I can always use this function

func x = gf x

There are still two pattern matches but in case of more complex functions expecting more than one argument it is useful to avoid a lot of pattern matches

i.e

addValues (Leaf (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e 
addValues (Leaf (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e 
addValues (Leaf (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e 
addValues (Leaf (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e 
addValues (Node (a, b)) (Leaf (c, d)) (Leaf (e, f)) = a + c + e 
addValues (Node (a, b)) (Leaf (c, d)) (Node (e, f)) = a + c + e 
addValues (Node (a, b)) (Node (c, d)) (Leaf (e, f)) = a + c + e 
addValues (Node (a, b)) (Node (c, d)) (Node (e, f)) = a + c + e

can now be written as

addValues (a, b, c) = (gf a) + (gf b) + (gf c)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.