Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use if-then-else statement with no else condition in Haskell?

Tags:

haskell

I have a list of relations and I wish to print the names of all fathers. Since there's no else condition, the following code doesn't work:

relations = [("father", "arushi", "anandan"), ("mother", "arushi", "abigale"), ("father", "anandan", "ayuta"), ("mother", "anandan", "akanksha")]

father ((r, c, f):xs) = if r == "father" then print(f)

main = do
    father (relations)

I do not wish to put any statement after else.

like image 841
Swapnil Sharma Avatar asked May 22 '18 17:05

Swapnil Sharma


2 Answers

Too bad, all ifs come with elses. But that's okay, there's a distinguished do-nothing IO action.

father ((r, c, f):xs) = if r == "father" then print f else return ()

There are many other ways to skin this cat. One is pattern matching.

father (("father", c, f):xs) = print f
father ((r, c, f):xs) = return ()

Another that is specific to monadic actions is to use when.

father ((r, c, f):xs) = when (r == "father") (print f)

Of course, that's just hiding the else, which is again return ():

when p act = if p then act else pure () -- okay, it's actually pure, not return
like image 154
Daniel Wagner Avatar answered Sep 18 '22 22:09

Daniel Wagner


The idiomatic Haskell way to solve such issues is to avoid mixing computation and I/O, when possible.

In this case, instead of "printing the names of all fathers", you can first "compute the names of all fathers" (no I/O here) and then "print the computed names" (I/O here)

relations = 
   [ ("father", "arushi", "anandan")
   , ("mother", "arushi", "abigale")
   , ("father", "anandan", "ayuta")
   , ("mother", "anandan", "akanksha")
   ]

-- compute only the fathers
fathers = [ f | ("father", _, f) <- relations ]

-- print them
main :: IO ()
main = mapM_ putStrLn fathers

No if needed, since mapM_ iterates over the list for us, and all the list entries have to be printed.

like image 23
chi Avatar answered Sep 19 '22 22:09

chi