user11783767
user11783767

Reputation:

Haskell - Double guard expression = "parse error on input `|'"?

I am currently working on some algorithms for binary trees. However, I came around a problem I cannot quite solve. I always get following error:

error: parse error on input ‘|’

While I understand that this has to do with spacing, I think I should have done it correctly.

delTree a Leaf = error "No tree here!"
delTree a (Branch left w right)
          | a < w = delTree a left
          | a > w = delTree a right
          | a == w 
                      | ...

Am I missing something? Does it have to do with using the guard expression twice?

Edit: This is my data structure

data BinTree a = Leaf | Branch (BinTree a) a (BinTree a) deriving Show

With delTree I am trying to delete a node in a binary tree. The only way I see is by of course looking for the proper value and then replacing it with the left or right child (depends on if there is a left child). If there is another way then doing it with nested guards I am open for advice!

Upvotes: 0

Views: 232

Answers (2)

chepner
chepner

Reputation: 531868

A little repetition is not always a bad thing.

delTree a (Branch left w right)
          | a < w = delTree a left
          | a > w = delTree a right
delTree a (Branch left w right) | ...
                                | ...

If neither a < w nor a > w is true, you can assume that a == w must be true, and it can be left implied in the second definition. You might even go so far as to use three definitions, some with only a single guard.

delTree a (Branch left w _) | a < w = delTree a left
delTree a (Branch _ w right) | a > w = delTree a right
delTree a (Branch left w right) | ...

You might also consider using compare rather than the comparison operators.

delTree a (Branch left w right) = case compare a w of
                                     LT -> delTree a left
                                     GT -> delTree a right
                                     EQ -> ...

Upvotes: 0

K. A. Buhr
K. A. Buhr

Reputation: 51029

You could consider using the MultiWayIf extension. Unfortunately, there's a shift in syntax from = to -> that's a little jarring:

{-# LANGUAGE MultiWayIf #-}

delTree a Leaf = error "No tree here!"
delTree a (Branch left w right)
          | a < w = delTree a left
          | a > w = delTree a right
          | a == w
            = if | False -> error "whatever"
                 | True  -> error "something else"

but you could switch your outer guards to a multi-way "if" for a consistent look:

delTree a Leaf = error "No tree here!"
delTree a (Branch left w right)
  = if | a < w  -> delTree a left
       | a > w  -> delTree a right
       | a == w -> if | False -> error "whatever"
                      | True  -> error "something else"

Alternatively, consider a where helper before getting too fancy:

delTree a Leaf = error "No tree here!"
delTree a (Branch left w right)
          | a < w = delTree a left
          | a > w = delTree a right
          | a == w = found
  where found | False = error "whatever"
              | True  = error "something else"

Upvotes: 1

Related Questions