Home > Software design >  how to have multiple if statements in Haskell?
how to have multiple if statements in Haskell?

Time:11-11

like consider the following python code,


n = 4
if n>3 :
  n = 5
if n>2 :
  n = 6
if n>1 :
  n = 4

How to achieve this in haskell??

let n = 4
main :: IO()
main = do 
    if n>3 then let n = 5
    if n>2 then let n = 6
    if n>1 then let n = 4

Tried this but gives an error, looking for some modifications

CodePudding user response:

While the example is a bit contrived, the usual way to encode an if with multiple branches is to use a case-of with () as the scrutinee as follows:

main :: IO()
main = do 
    let x = case () of 
             _ | n > 3 -> 5
               | n > 2 -> 6
               | otherwise -> 4
    print x

Alternatively, this may also be encoded as guards of a helper function

f :: Int -> Int
f n | n > 3 = 5
    | n > 2 = 6
    | otherwise = 4

CodePudding user response:

As I commented there are some points of your program you should checkout

  • else must be used after if
  • You don't use let for top level declarations (as in let n = 4).
  • When you write if n>3 then let n=5 you are not changing the value of n because values are inmutables in Haskell

There are a few "idiomatic" ways you can rewrite your program

Use a chained if then else with prints

n = 4 -- no let in top level binding

main :: IO()
main = do  
    if n>3 then print 5  -- do not use let n=5 because n can't be mutated
      else if n>2 then print 6 
        else if n>1 then print 4 
          else print ()

Use an external function and guards (This is the most idiomatic)

f :: Int -> Int
f x | x > 3 = 5
    | x > 2 = 6
    | x > 1 = 4

n = 4
main = do
  print (f n)

Use MultyWayIf extension (This is more advance as it needs extensions to the language)

{-# LANGUAGE MultiWayIf #-}

n = 4

main :: IO()
main = do 
  let x = if | n > 3 -> 5
             | n > 2 -> 6
             | n > 1 -> 4
  print x
  • Related