0

I try to use guarded equation to define a function. Why does it not work in GHCi? Thanks.

Prelude> :{
Prelude| maxThree :: Integer -> Integer -> Integer -> Integer
Prelude| maxThree x y z
Prelude| x >= y && x >= z = x
Prelude| y >= z = y
Prelude| otherwise = z
Prelude| :}

<interactive>:77:1: error: Parse error in pattern: x >= y
Will Ness
  • 70,110
  • 9
  • 98
  • 181
Tim
  • 1
  • 141
  • 372
  • 590

1 Answers1

7

Your syntax is wrong. Don’t be confused by the fact that the prompt already contains |! What you’ve written is the following:

maxThree :: Integer -> Integer -> Integer -> Integer
maxThree x y z
x >= y && x >= z = x
y >= z = y
otherwise = z

As you can see, this is clearly wrong. Guards always start with a vertical bar |, but you’ve left it out. I assume you got confused by the fact that the Prelude| prompt already contains |; that is part of the UI of GHCi, and is not considered to be part of the code you type in. If you want to type a guard into GHCi, do it like this:

Prelude> :{
Prelude| maxThree :: Integer -> Integer -> Integer -> Integer
Prelude| maxThree x y z
Prelude|   | x >= y && x >= z = x
Prelude|   | y >= z = y
Prelude|   | otherwise = z
Prelude| :}

Note how I have typed the code into GHCi exactly the same as I would type it into a file, including the fact that the guards need to be indented relative to the start of the definition.

bradrn
  • 8,337
  • 2
  • 22
  • 51
  • Thanks. Do I have to indent for each guard? How many spaces for each indention? – Tim Jul 27 '19 at 23:00
  • 1
    @Tim It’s a general rule of Haskell: the body of an expression should be indented further than the beginning of that expression. Haskell uses _indentation-based parsing_, which means that your indentation determines the structure of the program. (If you’ve used Python, it’s the same concept.) For more detail, have a look at [the Haskell Wikibook page on indentation](https://en.wikibooks.org/wiki/Haskell/Indentation). And you can use any number of spaces; you just have to be consistent, otherwise the parser gets confused. – bradrn Jul 27 '19 at 23:07
  • 2
    @bradrn In this particular case you need not be consistent. Guards are not separate lines of a block (they don't have implicit semicolons inserted), so they merely all need to be indented more than their enclosing block, but each may be indented by a different amount from that block if you like. – Daniel Wagner Jul 28 '19 at 00:54
  • I didn’t know that @DanielWagner — thanks for explaining! – bradrn Jul 28 '19 at 01:12