-- Lecture 1 on Input/Output

-- Writing to and reading from the terminal

hw :: IO ()
hw = putStrLn "Hello, world!"

hw1 :: String
hw1 = "Hello, world!"

hg :: IO ()
hg = do { 
          putStrLn "Hello world!" ;
          putStrLn "Goodbye world!" 
        }

echo :: IO ()
echo = do { 
            putStr "Please enter a string: " ;
            s <- getLine                     ;
            putStrLn s ; putStrLn s 
          }          

echo1 :: IO ()
echo1 = do { 
             putStr "Please enter a string: " ;
             s <- getLine                     ;
             putStrLn (s ++ '\n':s) 
           }

echo2 :: IO ()
echo2 = do { 
             putStr "Please enter a string: "   ;
             s <- getLine                       ;
             putStrLn s                         ;
             putStr "and another one, please: " ;
             t <- getLine                       ;
             putStrLn (s ++ " " ++ t) 
           }

dictionary1 :: IO ()
dictionary1 =
 do en <- getLine
    case en of
      { 
        "apple"  -> putStrLn "pomme"  ; 
        "bread"  -> putStrLn "pain"   ;
        "butter" -> putStrLn "beurre" ;  
        "milk"   -> putStrLn "lait"   ; 
        _        -> putStrLn "sorry, don't know" 
      }


dictionary2 :: IO ()
dictionary2 = do { 
                  en <- getLine ;  
                  putStrLn (en2fr en) 
                 }

en2fr :: String -> String
en2fr en =
    case en of
      { 
        "apple"  -> "pomme"   ;   
        "bread"  -> "pain"    ; 
        "butter" -> "beurre"  ;
        "milk"   -> "lait"    ;
        _        -> "sorry, don't know"
      }

dictionary3 :: IO ()
dictionary3 = do {
                  en <- getLine        ;
                  let {fr = en2fr en}  ;
                  putStrLn fr
                 }

-- Loops

dictloop :: IO ()
dictloop = do {
               en <- getLine  ;
               if en == "" then return ()
                           else do {
                                    putStrLn (en2fr en) ;
                                    dictloop
                                    }
              }
                        
 
collect :: IO ()
collect = do {
               allwords <- coll "" ; 
               putStrLn allwords
             }
 where

  coll :: String -> IO String
  coll history = do {
                      s <- getLine            ;
                      case s of
                        ""  -> return history
                        _   -> coll (history ++ " " ++ s)
                    }

-- Solving a quadratic interatively

solve :: IO ()
solve = do {
            sa <- getLine ;
            sb <- getLine ;
            sc <- getLine ;         
            let { 
                 a   = read sa ; 
                 b   = read sb ; 
                 c   = read sc ;
                 x1  = roots a b c True ;
                 x2  = roots a b c False ;
                 sc1 = show x1 ;
                 sc2 = show x2 
                } ;
           putStrLn ("The solutions are " ++ sc1 ++ " and " ++ sc2)
          }

roots :: Float -> Float -> Float -> Bool -> Float
roots a b c p 

  | a /= 0     = let { d = b^2 - 4*a*c }
                 in if d >= 0 
                    then ((-b) + k * sqrt d) / (2*a)
                    else err

  | a == 0     = if b /= 0 then (-c)/b else err

 where k   = if p then 1 else (-1)
       err = error "no root or infinitely many roots"


