2

I was trying to nest guards which check for more than two conditions like so:

f :: Int -> Int
f i
   | bool1
       | bool2 = a
       | bool3 = a2
       | otherwise = a3
   | bool4
       | bool5 = a4
       | bool6 = a5
       | otherwise = a6
   | bool8
...
   | otherwise = an


which gives me a parse error. Is the proper way to do this
to flatten the guards with && or
to implement a function like so:

multiIf :: [Bool] -> [a] -> a
multiIf (x:xs) (l:ls) = if x then l else multiIf xs ls
multiIf _ _ = undefined

Or is there another method?

Laurens
  • 25
  • 3
  • 2
    Try the MultiWayIf extension. – Paul Johnson May 07 '19 at 18:51
  • Does this imply that if `bool7` is false, the outer branch is considered again and `bool8` is evaluated, and so on? Your `multiIf` does not do that, AFAICS. – chi May 07 '19 at 19:06
  • @chi Thanks, I meant to use otherwise – Laurens May 07 '19 at 19:08
  • 1
    while I'd admit it's not particularly nice, if you really need to write this sort of function then I'd probably just make a big `if/then/else` tree, with the proper indentation. – Robin Zigmond May 07 '19 at 19:08
  • 1
    @RobinZigmond Minor point: technically `if` does not require any indentation (but pragmatically writing a large nested `if` without proper indentation leads to unreadable code, so its' still strongly recommended). – chi May 07 '19 at 20:02
  • @chi, understood and agreed - that's all I meant – Robin Zigmond May 07 '19 at 20:07
  • Possible duplicate of [Is it possible to nest guards in Haskell?](https://stackoverflow.com/questions/34124558/is-it-possible-to-nest-guards-in-haskell) – moonGoose May 07 '19 at 20:50

1 Answers1

3

Not directly, but the MultiWayIf extension can get you a very similar style.

{-# LANGUAGE MultiWayIf #-}

f :: Int -> Int
f i
   | bool1
       = if | bool2 -> a
            | bool3 -> a2
            | otherwise -> a3
   | bool4
       = if | bool5 -> a4
            | bool6 -> a5
            | otherwise -> a6
   | bool8
...
   | otherwise = an