a monadic if or case?

Keith Wansbrough Keith.Wansbrough@cl.cam.ac.uk
Thu, 13 Feb 2003 17:11:12 +0000


> Not with the syntactic sugar of 'if'.
> But you can write [warning: untested code ahead]
> 
> ifM :: IO Bool -> IO a -> IO a -> IO a
> ifM test yes no = do 
>    b <- test
>    if b then yes else no

There is a little trick that allows you to "sort-of" get the syntactic sugar.  It goes like this [warning: also untested code]:

data Then_ = Then_
data Else_ = Else_
then_ = Then_
else_ = Else_

ifM :: IO Bool -> Then_ -> IO a -> Else_ -> IO a -> IO a
ifM test Then_ yes Else_ no = do
  b <- test
  if b then yes else no

and then you can write

ifM (doesDirectoryExist f)
  then_ (return "dir")
  else_ (ifM (doesFileExist f)
           then_ (return "file")
           else_ (return "nothing"))

Note that this doesn't save you any parentheses, sadly, although there may be tricky ways to do that.

References:

LATOS uses this syntax; see http://www.dsse.ecs.soton.ac.uk/techreports/97-1.html
[Pieter H. Hartel, 1997, LATOS - A Lightweight Animation Tool for Operational Semantics]

http://www.eecs.usma.edu/Personnel/okasaki/pubs.html#hw02 [Chris Okasaki, Haskell Workshop 2002, Techniques for embedding postfix languages in Haskell]

Enjoy!

--KW 8-)
-- 
Keith Wansbrough <kw217@cl.cam.ac.uk>
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.