    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeOperators, GeneralizedNewtypeDeriving, Trustworthy #-}
    module System.Console.Wizard.BasicIO
            ( BasicIO
            , basicIO
            ) where
    import System.Console.Wizard
    import System.Console.Wizard.Internal
    import Control.Monad.Trans
    import Control.Monad.Trans.Maybe

    instance Run IO Output      where runAlgebra :: forall v. Output (IO v) -> IO v
    runAlgebra (Output String
    s IO v
    w)        = String -> IO ()
    putStr String
    s   IO () -> IO v -> IO v
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> IO v
    w
    instance Run IO OutputLn    where runAlgebra :: forall v. OutputLn (IO v) -> IO v
    runAlgebra (OutputLn String
    s IO v
    w)      = String -> IO ()
    putStrLn String
    s IO () -> IO v -> IO v
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> IO v
    w
    instance Run IO Line        where runAlgebra :: forall v. Line (IO v) -> IO v
    runAlgebra (Line String
    s String -> IO v
    w)          = IO String
    getLine    IO String -> (String -> IO v) -> IO v
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String -> IO v
    w
    instance Run IO Character   where runAlgebra :: forall v. Character (IO v) -> IO v
    runAlgebra (Character String
    s Char -> IO v
    w)     = IO Char
    getChar    IO Char -> (Char -> IO v) -> IO v
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Char -> IO v
    w
    instance Run IO ArbitraryIO where runAlgebra :: forall v. ArbitraryIO (IO v) -> IO v
    runAlgebra (ArbitraryIO IO a
    iov a -> IO v
    f) = IO a
    iov        IO a -> (a -> IO v) -> IO v
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> IO v
    f

    -- | The 'BasicIO' backend supports only simple input and output.
    --   Support for 'Password' and 'LinePrewritten' features can be added with
    --   a shim from 'System.Console.Wizard.Shim'.
    newtype BasicIO a = BasicIO (( Output
                               :+: OutputLn
                               :+: Line
                               :+: Character
                               :+: ArbitraryIO) a)
                      deriving ( (:<:) Output
                               , (:<:) OutputLn
                               , (:<:) Line
                               , (:<:) Character
                               , (:<:) ArbitraryIO
                               , (forall a b. (a -> b) -> BasicIO a -> BasicIO b)
    -> (forall a b. a -> BasicIO b -> BasicIO a) -> Functor BasicIO
    forall a b. a -> BasicIO b -> BasicIO a
    forall a b. (a -> b) -> BasicIO a -> BasicIO b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> BasicIO a -> BasicIO b
    fmap :: forall a b. (a -> b) -> BasicIO a -> BasicIO b
    $c<$ :: forall a b. a -> BasicIO b -> BasicIO a
    <$ :: forall a b. a -> BasicIO b -> BasicIO a
    Functor
                               , Run IO
                               )

    -- | A simple identity function, used to restrict types if the type inferred by GHC is too general.
    --   You could achieve the same effect with a type signature, but this is slightly less typing.
    basicIO :: Wizard BasicIO a -> Wizard BasicIO a
    basicIO :: forall a. Wizard BasicIO a -> Wizard BasicIO a
    basicIO = Wizard BasicIO a -> Wizard BasicIO a
    forall a. a -> a
    id