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
.
Too bad, all if
s come with else
s. 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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With