module Main where


-- given:
readMaybe :: (Read a) => String -> Maybe a
getLine :: IO String
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
return :: (Monad m) => a -> m a

-- suppose: 
eBindBad :: IO (Maybe Int)
eBindBad =
  getLine >>= (\input1 ->
  getLine >>= (\input2 -> 
    (readMaybe input1 >>= (\x ->
     readMaybe input2 >>= (\y ->
     return $ x + y))) >>= 
  (\z ->
    case z of 
    Nothing -> putStrLn "something went wrong" >>= (\_ ->
               return Nothing)
    Just z'  -> putStrLn (show z') >>= (\_ ->
                return (Just z'))))))

-- and it's translation into do notation.
eDoBad :: IO (Maybe Int)
eDoBad = do
  input1 <- getLine
  input2 <- getLine 
  z <- do
    x <- readMaybe input1
    y <- readMaybe input2
    return $ x + y
  case z of
    Nothing -> do
      putStrLn "something went wrong"
      return Nothing
    Just z' -> do
      putStrLn (show z')
      return (Just z')

-- These expressions contain a type error with respect to monadic bind
-- Questions:
--   1) What is the type of `z` on the third line?
--   2) What is the type of `return $ x + y` on the sixth line?
--   3) Describe the type error


-- 4) Rewrite the bind so that it will type check
eRewritten :: IO (Maybe Int)
eRewritten = 

-- 5) Translate it into do notation
e0DoRewritten :: IO (Maybe Int)
eDoReWritten = do









e0Correct :: IO (Maybe Int) e0Correct = do input1 <- getLine input2 <- getLine let z = do x <- readMaybe input1 y <- readMaybe input2 return $ x + y case z of Nothing -> do putStrLn "something went wrong" return Nothing Just z' -> do putStrLn (show z') return (Just z')