Reputation: 1
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
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
Reputation: 5063
As I commented there are some points of your program you should checkout
else
must be used after iflet
for top level declarations (as in let n = 4
).if n>3 then let n=5
you are not changing the value of n
because values are inmutables in HaskellThere are a few "idiomatic" ways you can rewrite your program
Use a chained if then else
with print
s. 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