-- code_2009_03_06.hs
-- Glenn G. Chappell
-- 6 Mar 2009
--
-- For CS 331 Spring 2009
-- Sample Haskell code
-- From the Friday, March 6, 2009 class meeting

module Main where

import IO  -- for file I/O functions: openFile, hGetContents, ...


-- ---------------------------------------------------------------------
-- Code from topic Haskell: I/O
-- ---------------------------------------------------------------------


-- File I/O
-- Do "import IO" (see above)

-- openFile takes filename & mode, returns "handle".
-- "h" I/O functions take a handle as their first param.
-- printFile: read file with given name and prints it
printFile fileName =  do
    h <- openFile fileName ReadMode
    lines <- hGetContents h
    putStr lines

-- Handles stdin, stdout, stderr are predefined
-- Normal I/O functions are generally "h" functions in disguise.
-- For example:
--
-- getLine = hGetLine stdin


-- ---------------------------------------------------------------------
-- Code from topic Haskell: Types, Type Classes, Monads
-- ---------------------------------------------------------------------


-- Declaring a new data type
data IntegerAndBool = IB (Integer, Bool)


-- Putting a type into a type class
-- Here we put IntegerAndBool into class Eq, and define the == operator.
-- The compiler defines /= in the obvious way.
instance Eq IntegerAndBool where
    IB (i1, b1) == IB (i2, b2)  =  (i1 == i2) && (b1 == b2)

-- Monad is a type class for wrappers, where wrapped values are
-- things we can "do". IO is a monad. So is List.
-- Thus, we can "do" lists:
listOfPairs = do
    a <- [1,2,3]
    b <- [10,20,30]
    return (a, b)

-- Below is equivalent of above using list-comprehension notation
listOfPairs_b = [(a,b) | a <- [1,2,3], b <- [10,20,30]]

