module Test.IOTasks.MonadTeletype (
  MonadTeletype(..),
  ) where

import Prelude hiding (putChar, putStr, putStrLn, print, getChar, getLine, readLn)
import qualified Prelude

import System.IO (hSetBuffering, Handle, BufferMode)

class Monad m => MonadTeletype m where
  putChar :: Char -> m ()
  getChar :: m Char

  putStr :: String -> m ()
  putStr = (Char -> m ()) -> String -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Char -> m ()
forall (m :: * -> *). MonadTeletype m => Char -> m ()
putChar
  putStrLn :: String -> m ()
  putStrLn = String -> m ()
forall (m :: * -> *). MonadTeletype m => String -> m ()
putStr (String -> m ()) -> (String -> String) -> String -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\n")
  print :: Show a => a -> m ()
  print = String -> m ()
forall (m :: * -> *). MonadTeletype m => String -> m ()
putStrLn (String -> m ()) -> (a -> String) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

  getLine :: m String
  getLine = do
    Char
c <- m Char
forall (m :: * -> *). MonadTeletype m => m Char
getChar
    case Char
c of
      Char
'\n' -> String -> m String
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
""
      Char
_ -> (Char
c:) (String -> String) -> m String -> m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). MonadTeletype m => m String
getLine

  readLn :: Read a => m a
  readLn = String -> a
forall a. Read a => String -> a
read (String -> a) -> m String -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). MonadTeletype m => m String
getLine

  -- | for compatibility with regular IO programs.
  --
  --   Defaults to
  --   @
  --   hSetBuffering _ _ = pure ()
  --   @.
  hSetBuffering :: Handle -> BufferMode -> m ()
  hSetBuffering Handle
_ BufferMode
_ = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

instance MonadTeletype IO where
  putChar :: Char -> IO ()
putChar = Char -> IO ()
Prelude.putChar
  getChar :: IO Char
getChar = IO Char
Prelude.getChar

  putStr :: String -> IO ()
putStr = String -> IO ()
Prelude.putStr
  putStrLn :: String -> IO ()
putStrLn = String -> IO ()
Prelude.putStrLn
  print :: forall a. Show a => a -> IO ()
print = a -> IO ()
forall a. Show a => a -> IO ()
Prelude.print

  getLine :: IO String
getLine = IO String
Prelude.getLine
  readLn :: forall a. Read a => IO a
readLn = IO a
forall a. Read a => IO a
Prelude.readLn

  hSetBuffering :: Handle -> BufferMode -> IO ()
hSetBuffering = Handle -> BufferMode -> IO ()
System.IO.hSetBuffering