content: {- Author:     Jeff Newbern
     Maintainer: Jeff Newbern <jnewbern@nomaware.com>
     Time-stamp: <Wed Aug 13 10:58:14 2003>
     License:    GPL
  -}
  
  {- DESCRIPTION
  
  Example 6 - Using the lifting functions
  
  Usage: Compile the code and execute the resulting program
         with a name as the argument.  If the name is in the
         database, it will retrieve the full name and print
         it in first+last order.
  
  Try: ./ex6 "John"
       ./ex6 "Mike"
       ./ex6 "Fred"
  -}
  
  import Monad
  import System
  import Char (isSpace)
  
  -- swapNames converts a string like "Smith, John" into "John Smith"
  swapNames :: String -> String
  swapNames s = let (ln,fn) = break (==',') s
                in (dropWhile isSpace (tail fn)) ++ " " ++ ln
  
  -- getName looks up the name in the database and returns the
  -- name in first+last order.
  -- It uses the liftM operator to convert swapName from operating
  -- on Strings to operating on Maybe Strings.
  getName :: String -> Maybe String
  getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]
                    liftM swapNames (lookup name db)
  
  {- Without using the liftM operation, we would have had to do something
     that is less succinct, like this:
  
  getName name = do let db = [("John", "Smith, John"), ("Mike", "Caine, Michael")]
                    tempName <- lookup name db
  	          return (swapNames tempName)
  -}
  
  -- This looks up the person and prints the name first then last.
  -- it uses the lift operation to lift the swapNames function into
  -- the Maybe monad, so that it can operate on Maybe String values.
  main :: IO ()
  main = do args <- getArgs
            case getName (args!!0) of
              Just n  -> print n
              Nothing -> putStrLn "No such person in the database"
  
  -- END OF FILE