{---------------------------------------------------------------    
 Datei mit Beispieldefinitionen zur monadischen Ein-/Ausgabe
----------------------------------------------------------------}

{- Basisdefinitionen:

type IO a = World -> (a, World) 

-- Erzeugung von Aktionen aus Werten
return :: a -> IO a

-- do-Notation zur Komposition von Aktionen
do <action1>
   <action2> 
     ...
   <actionk>

-- mit Wertuebergabe
do <variable vom Typ a> <- <action vom Typ IO a>
   <Aktion mit Verwendung der neuen Variablen>

-- mit lokalen Definitionen
do let <variable vom Typ a> = <Ausdruck vom Typ a>
   <Aktion mit Verwendung der neuen Variablen>
   
   

-- elementare IO-Aktionen
putChar :: Char ->  IO ()
getChar :: IO Char

-- vordefinierte Ein-/Ausgabe von Zeichenketten:
putStr        :: String -> IO ()
putStr []     =  return ()
putStr (c:cs) =  do putChar c
                    putStr cs

getLine :: IO String
getLine =  do c <- getChar
              if c == '\n' then return [] -- newline gehoert nicht 
                                          -- zum String
                           else do cs <- getLine
                                   return (c:cs)

--}


----------------------------
-- Palindromueberpruefung --
----------------------------

palindrome    :: String -> Bool
palindrome cs =  cs == reverse cs

prompt :: String
prompt =  "Type in a line, please!\n"


mainPal :: IO ()
mainPal =  do putStr prompt
              line <- getLine
              if null line then putStr "Good bye!" 
                           else do check line 
                                   mainPal

check    :: String -> IO ()
check cs | palindrome cs = putStr (cs ++ " is a palindrome!\n")
         | otherwise     = putStr (cs ++ " is not a palindrome!\n")
         
         
------------------------------------------
-- Einlesen und Aufsummieren von Zahlen --
------------------------------------------

f     :: Int -> IO Int
f sum =  do val <- getInt
            if val == 0 then return sum
             else let newSum = val + sum in
                  do putStr ("Summe: " ++ show newSum 
                                   ++ '\n':"Naechste Zahl?")
                     f newSum

getInt :: IO Int
getInt =  do line <- getLine 
             return (if null line then 0 else read line)

main :: IO ()
main =  do putStr ("Erste Zahl?")
           erg <- f 0
           putStr ("\nEndergebnis:" ++ show erg)


-------------------------------
-- Manipulation von Dateien  --
-------------------------------

{- vordefinierte Funktionen

type FilePath = String

writeFile  :: FilePath -> String -> IO ()
appendFile :: FilePath -> String -> IO ()
readFile   :: FilePath -> IO String 

-}

copyFile :: FilePath -> FilePath -> IO ()
copyFile from to = do contents <- readFile from
                      writeFile to contents


-------------------------------
-- Kontrollstrukturen        --
-------------------------------

-- n-fache Wiederholung einer IO-Aktion
repeatN     :: Int -> IO a -> IO ()
repeatN 0 a =  return ()
repeatN n a =  do a 
                  repeatN (n-1) a

test0 = repeatN 5 (putChar 'a')

-- Sequenzen
{- 
-- vordefiniert 
sequence        :: [IO a] -> IO [a]
sequence []     =  return []
sequence (a:as) =  do r  <- a
                      rs <- sequence as 
                      return (r:rs)

sequence_        :: [IO a] -> IO ()
sequence_ []     =  return ()
sequence_ (a:as) =  do r  <- a
                       rs <- sequence as 
                       return ()

-}
