23

Sometimes I write code like this

solveLogic :: Int -> Int -> Int
solveLogic a b =
    let 
        x = 1
        brainiac
            | a >= x     = 1
            | a == b     = 333
            | otherwise  = 5
    in
        brainiac

And every time I have urge to write this things without unneeded "brainiac" function, like this:

solveLogic :: Int -> Int -> Int
solveLogic a b =
    let 
        x = 1
    in
        | a >= x     = 1
        | a == b     = 333
        | otherwise  = 5

Which code is much more "Haskellish". Is there any way of doing this?

Rijk
  • 612
  • 1
  • 7
  • 14

2 Answers2

54

Yes, using a where clause:

solveLogic a b
        | a >= x     = 1
        | a == b     = 333
        | otherwise  = 5
    where
      x = 1
huon
  • 94,605
  • 21
  • 231
  • 225
16

When I want guards as an expression I use this somewhat ugly hack

case () of
_ | a >= x     -> 1
  | a == b     -> 333
  | otherwise  -> 5
augustss
  • 22,884
  • 5
  • 56
  • 93
  • It has to be `->` instead of `=` for case-statement guards. All but the first `_` can be left out. – leftaroundabout Apr 29 '12 at 11:54
  • 7
    A minor note for future readers: this trick can now be replaced with `if | a >= x -> 1 | a == b -> 333 | otherwise -> 5` using the `MultiWayIf` extension, which has been available since GHC 7.6. – Jon Purdy Mar 28 '18 at 12:42