--------------------------------------------------
--  IO Exceptions in Haskell
--
--  userError :: String -> IOError
--  ioError   :: IOError -> IO a
--  catch     :: IO a -> (IOError -> IO a) -> IO a
--  
--------------------------------------------------

------------------------------------------------
-- Einlesen und Aufsummieren von Zahlen       --
-- mit Restriktion der Eingabe auf Zahlen <10 --
------------------------------------------------

f     :: Int -> IO Int
f sum =  do val <- getInt
            if val == 0 then return sum
-- Ausnahmebehandlung: "raise exception" bei Eingabe >= 10
             else if val >= 10 
                  then ioError (userError "Nur Zahlen <10 sind als Eingabe erlaubt!")
-- Ende Ausnahmebehandlung
                   else let newSum = val + sum in
                         do putStr ("Summe: " ++ show newSum 
                                              ++ '\n':"Naechste Zahl?")
                            f newSum

getInt :: IO Int
getInt =  do line <- getLine 
             return (toNumber line 0) -- (if null line then 0 else read line)

toNumber          :: String -> Int -> Int
toNumber []     s =  s
toNumber (c:cs) s =  toNumber cs (s*10 + (fromEnum c - fromEnum '0'))

-- (toNumber line 0) kann auch durch (if null line then 0 else read line) 
-- ersetzt werden!

main :: IO ()
main = ( do putStr ("Erste Zahl?")
            erg <- f 0
            putStr ("\nEndergebnis:" ++ show erg)
       ) 
-- Ausnahmebehandlung: Fehlermeldung ausgeben und Neustart       
       `catch` (\ err -> do { putChar '\n' ;
	                            putStr (show err ++ " -> Restart!\n");
	                            main }
	                )
