repl-toolkit-0.1.0.0: Toolkit for quickly whipping up command-line interfaces.

Safe HaskellNone
LanguageHaskell2010

System.REPL

Contents

Description

Functions to expedite the building of REPLs.

Synopsis

String-generic versions of Prelude Functions

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 newcline character, to stderr.

Feture-rich reading of user-input

These functions automate parsing and validating command-line input via the Asker type.

It is possible to ask for Strings, but then quotes will be required around them (per their Read-instance). If you want to get the user's input as-is, use the Verbatim type.

data Asker m a Source

The description of an 'ask for user input'-action. The type parameters are the used monad (typically IO), the type of the read value and the type of the error that is thrown in case of failures.

Constructors

Asker 

Fields

askerPrompt :: Text

The prompt to be displayed to the user.

askerParser :: Text -> Either Text a

The parser for the input value, which either delivers a value of type a or an error message.

askerPredicate :: a -> m (Either Text Success)

The predicate which the input, once read, must fulfill. It either delivers Success or an error message.

data Success Source

Singleton type representing success.

Constructors

Success 

data AskFailure Source

Represents a failure of an ask function. It can either be a type failure (failure to interpret the user input as a value of the required type) or a predicate failure (the user input could be interpreter as a value of the required type, but it failed some user-supplied test).

Constructors

TypeFailure Text

Indicates that the parsing as the required type failed.

PredicateFailure Text

Indiciates that the parsed value failed a predicate.

ParamFailure Text

Indicates that an incorrect number of parameters was passed.

NothingFoundFailure

Indicates that no action was appropriate to the given input.

asker Source

Arguments

:: (Monad m, Functor m, Read a) 
=> Text

The prompt.

-> Text

Type error message.

-> Text

Predicate error message.

-> (a -> m Bool)

Predicate.

-> Asker m a 

Creates a general Asker with readMaybe as its parser. This suffices for most simple values. The main drawback of using readMaybe is that the input Text is unpacked into a String, which incurs a performance hit. For short (one-line) input. this isn't important, but if large ones are expected, it's better to pass a custom, Text-compatible parsing function, such as a parsec-parser.

typeAsker Source

Arguments

:: (Monad m, Functor m, Read a) 
=> Text

The prompt.

-> Text

Type error message.

-> Asker m a 

Creates an Asker which just cares about the type of the input.

predAsker Source

Arguments

:: (Monad m, Functor m) 
=> Text

The prompt.

-> Text

Predicate error message.

-> (Text -> m Bool)

The predicate.

-> Asker m Verbatim 

Creates an Asker which takes its input verbatim as Text.

maybeAsker Source

Arguments

:: (Monad m, Functor m, Read a) 
=> Text

The prompt.

-> Text

Type error message.

-> Text

Predicate error message.

-> (a -> m Bool)

Predicate.

-> Asker m (Maybe a) 

An asker which asks for an optional value. If only whitespace is entered (according to isSpace), it returns Nothing without further parsing or checking; otherwise, it behaves identically to asker.

prompt :: (MonadIO m, Functor m, ListLikeIO full item) => m full Source

Prints > and asks the user to input a line.

prompt' :: (MonadIO m, Functor 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.

newtype Verbatim Source

A verbatim Text whose Read instance simply returns the read string, as-is. This is useful for askers which ask for strings without quotes.

Constructors

Verbatim 

Fields

fromVerbatim :: Text

Extracts a Verbatim's Text.

Instances

Read Verbatim

Read-instance for Verbatim. Wraps the given value into quotes and reads it a a Text.

Asking for input

ask :: (MonadIO m, MonadError SomeException m, Functor m, Read a) => Asker m a -> Maybe Text -> m 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. If the input is of the wrong type, an error-message is printed and the user is asked again. In addition to the condition that the input must be of the correct type, it must also fulfill a predicate.

Since the predicate is of monadic, arbitrarily complex tests can be performed: checking whether an item is in a database, whether a date was less than x years ago, etc.

ask' :: (MonadIO m, MonadError SomeException m, Functor m, Read a) => Asker m a -> m a Source

See ask. Always reads the input from stdin. ask' a = ask a Nothing.

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.