{- Author:     Jeff Newbern
   Maintainer: Jeff Newbern <jnewbern@nomaware.com>
   Time-stamp: <Fri Aug 15 08:40:08 2003>
   License:    GPL
-}

{- DESCRIPTION

Example 10 - Using the guard function

Usage: Compile the code and execute the resulting program
       with an integer as its argument.  It will print the
       records for everyone in the database younger than
       the specified age.
       
Try: ./ex10 21
     ./ex10 40
     ./ex10 38
     ./ex10 10
     ./ex10 2
-}

import System
import Maybe
import Monad

-- we have records containing name and age
data Record = Rec {name::String, age::Int} deriving Show

-- we collect the records into a "database"
type DB = [Record]

-- getYoungerThan returns all records for people younger than a specified age.
-- It uses the guard function to eliminate records for ages at or over the limit.
-- This is just for demonstration purposes.  In real life, it would be
-- clearer to simply use filter.  When the filter criteria are more complex,
-- guard becomes more useful.
getYoungerThan :: Int -> DB -> [Record]
getYoungerThan limit db =
  mapMaybe (\r -> do { guard (age r < limit); return r }) db

-- list the records for people younger than the age given in args!!0
main :: IO ()
main = do let db = [Rec "Marge" 37, Rec "Homer" 38, Rec "Bart" 11, Rec "Lisa" 8, Rec "Maggie" 2]
          args <- getArgs
          print $ getYoungerThan (read (args!!0)) db

-- END OF FILE
