module Prelude.Week1 (
  -- * Basic Types
  Char, String, Int, Double, Bool,

  -- * Arithmetic arithmetic and comparison
  -- ** Integer arithmetic and comparison
  (+), (-), (*), mod, (>), (<), (>=), (<=), (==), (/=),

  -- ** Double arithmetic and comparison
  (+.), (-.), (*.), (>.), (<.), (>=.), (<=.), (==.), (/=.),

  -- * Type conversion functions
  doubleToString, intToString, charToString, intToDouble, intToChar, charToInt,

  -- * IO Requests and responses
  IORequest(..), IOResponse(..), run,

  -- * String operations
  (<>),

  -- * Other convenient operators
  (.), trace,

  -- List operators
  module Data.List

  ) where

import qualified Prelude as P
import qualified Data.Char
import Prelude (fmap, map, (>>), (>>=), return, putStrLn, getLine, readFile, ($), print, (.), mapM, IO)

import System.IO.Unsafe (unsafePerformIO)
import Control.DeepSeq (deepseq, NFData)
import System.Exit (exitSuccess)

import Prelude.Week0
import Data.List

-- IO requests and responses
data IORequest = PrintString String
               | Exit
               | ReadString
               | ReadFile String
instance NFData IOResponse

data IOResponse = Success
                | FileContents String
                | NextLine String

run :: ([IOResponse] -> [IORequest]) -> IO ()

run main = deepseq responses $ return ()
  where 
    requests = main responses
    responses = map (unsafePerformIO . processRequest) requests

    processRequest Exit = exitSuccess >> return Success
    processRequest (PrintString str) = putStrLn str >> return Success
    processRequest ReadString  = fmap NextLine getLine
    processRequest (ReadFile filename) = P.fmap FileContents (readFile filename)