how to have multiple if statements in Haskell?

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

Upvotes: 0

Views: 946

Answers (2)

dminuoso
dminuoso

Reputation: 76

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 
    case () of 
             _ | n > 3 -> ...
               | n > 2 -> ...
               | otherwise -> ...

or when part of a binding, by use of a guarded let

let x | n > 3 = ...
      | n > 2 = ...
      | otherwise = ...

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

Updated to include @Iceland_jack's comment

Upvotes: 2

lsmor
lsmor

Reputation: 5063

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. This is the closest to your code

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)

As @davidflecher commented, you can use guards within a let binding

n = 4

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

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

Upvotes: 2

Related Questions