Safe Haskell | None |
---|---|
Language | Haskell2010 |
Functions to expedite the building of REPLs.
- module Data.ListLike.IO
- putErr :: ListLikeIO full item => full -> IO ()
- putErrLn :: ListLikeIO full item => full -> IO ()
- prompt :: (MonadIO m, ListLikeIO full item) => m full
- prompt' :: (MonadIO m, ListLikeIO full item, ListLikeIO full' item') => full -> m full'
- promptAbort :: (MonadIO m, ListLikeIO full item, ListLikeIO full' Char) => Char -> full -> m (Maybe full')
- type PromptMsg = Text
- type TypeErrorMsg = Text
- type PredicateErrorMsg = Text
- type Predicate m a = a -> m Bool
- type Parser a = Text -> Either Text a
- data Asker m a = Asker {
- askerPrompt :: Text
- askerParser :: Parser a
- askerPredicate :: a -> m (Either Text ())
- data AskFailure
- askerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m a
- typeAskerP :: (Monad m, Functor m) => PromptMsg -> Parser a -> Asker m a
- maybeAskerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m (Maybe a)
- readParser :: Read a => TypeErrorMsg -> Text -> Either Text a
- asker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m a
- typeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> Asker m a
- predAsker :: (Monad m, Functor m) => PromptMsg -> Text -> (Text -> m Bool) -> Asker m Verbatim
- maybeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m (Maybe a)
- newtype Verbatim = Verbatim {
- fromVerbatim :: Text
- ask :: (MonadIO m, MonadError SomeException m, Functor m) => Asker m a -> Maybe Text -> m a
- ask' :: (MonadIO m, MonadError SomeException m, Functor m) => Asker m a -> m a
- askEither :: (MonadIO m, Functor m) => Asker m a -> Maybe Text -> m (Either AskFailure a)
- untilValid :: (MonadIO m, MonadError SomeException m, Functor m, Read a) => m a -> m a
String-generic versions of Prelude Functions
module Data.ListLike.IO
putErr :: ListLikeIO full item => full -> IO () Source
Prints a string to stderr.
putErrLn :: ListLikeIO full item => full -> IO () Source
Prints a string, followed by a newline character, to stderr.
prompt :: (MonadIO m, ListLikeIO full item) => m full Source
Prints >
and asks the user to input a line.
Prompts
prompt' :: (MonadIO m, ListLikeIO full item, ListLikeIO full' item') => full -> m full' Source
Prints its first argument and, in the same line, asks the user to input a line.
promptAbort :: (MonadIO m, ListLikeIO full item, ListLikeIO full' Char) => Char -> full -> m (Maybe full') Source
The same as prompt, but aborts as soon as the user presses a given key
(commonly '\ESC'
). This function temporarily tries to set the buffering mode
to NoBuffering via hSetBuffering
, which may not be supported.
See the documentation of hSetBuffering
for details.
Feture-rich reading of user-input
These functions automate parsing and validating command-line
input via the Asker
type.
type TypeErrorMsg = Text Source
An error message indicating that a value wasn't able to be parsed.
type PredicateErrorMsg = Text Source
An error message indicating that a value failied a predicate.
type Parser a = Text -> Either Text a Source
A parser which either returns a parsed value or an error message.
The description of an 'ask for user input'-action.
The type parameters are the used monad (typically IO
or ExceptT
),
the type of the read value and the type of the error that is thrown
in case of failures.
The components are a prompt, a parser, and a predicate that the parsed value must fulfil. The predicate, being monadic, can perform arbitrarily complex tests, such as checking whether a given date is in the future, whether an item is in a database, whether a file with a given name exists, etc.
Asker | |
|
data AskFailure Source
Represents a failure during the running of an asking function. Either the input was incorrect in some way, or the process was aborted by the user.
TypeFailure TypeErrorMsg | The input wasn't able to be parsed. |
PredicateFailure PredicateErrorMsg | The parsed value failed a predicate. |
ParamFailure Text | An incorrect number of parameters was passed. |
NothingFoundFailure | No action was appropriate for the given input. |
AbortFailure | The input was aborted by the user. |
askerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m a Source
Creates a general Asker
with a custom parsing function and a predicate
that the parsed value has to pass. If either the parsing or the predicate
fail, one of the given error messages is displayed.
typeAskerP :: (Monad m, Functor m) => PromptMsg -> Parser a -> Asker m a Source
Creates an Asker
which only cares about the type of the input.
maybeAskerP :: (Monad m, Functor m) => PromptMsg -> PredicateErrorMsg -> Parser a -> Predicate m a -> Asker m (Maybe a) Source
Asking based on Read
These askers use readMaybe
as their parser.
It is possible to ask for Strings, but then quotes will be required
around them (per their Read-instance). To get the user's
input as-is, use the Verbatim
type.
readParser :: Read a => TypeErrorMsg -> Text -> Either Text a Source
A parser based on readMaybe
. This suffices for the parsing of
most data types.
asker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m a Source
typeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> Asker m a Source
Creates an Asker
based on Read which just cares about the type of the input.
maybeAsker :: (Monad m, Functor m, Read a) => PromptMsg -> TypeErrorMsg -> PredicateErrorMsg -> Predicate m a -> Asker m (Maybe a) Source
An asker based on Read which asks for an optional value.
A verbatim Text whose Read instance simply returns the read string, as-is. This is useful for askers which ask for strings without quotes.
Running askers
Since the parsing depends on the Read-instance, the expected result type must be explicitly given. E.g.:
intAsker :: Asker IO Int intAsker = typeAsker "> " "Expected Int!"
or, for polymorphic askers,
genericAsk :: Read a => Asker IO a genericAsk = typeAsker "> " "Couldn't parse value!" ... do (x :: Int) <- genericAsk (y :: Int) <- genericAsk putStrLn $ "The sum is: " ++ show (x+y)
ask :: (MonadIO m, MonadError SomeException m, Functor m) => Asker m a -> Maybe Text -> m a Source
Executes an Asker. If the process fails, an exception is thrown
The canonical instance of MonadError SomeException
is the ExceptT
monad.
ask' :: (MonadIO m, MonadError SomeException m, Functor m) => Asker m a -> m a Source
See ask
. Always reads the input from stdin.
ask' a = ask a Nothing
askEither :: (MonadIO m, Functor m) => Asker m a -> Maybe Text -> m (Either AskFailure a) Source
Executes an Asker
. If the Text argument is Nothing, the user is asked
to enter a line on stdin. If it is Just x
, x
is taken to be input.
untilValid :: (MonadIO m, MonadError SomeException m, Functor m, Read a) => m a -> m a Source
Repeatedly executes an ask action until the user enters a valid value. Error messages are printed each time.