wizards-1.0.3: High level, generic library for interrogative user interfaces

Safe Haskell | Trustworthy
Language | Haskell98

System.Console.Wizard.Internal

Synopsis

- newtype Wizard backend a = Wizard (MaybeT (Free backend) a)
- type PromptString = String
- data (f :+: g) w
  - = Inl (f w)
  - | Inr (g w)
- class (Functor sub, Functor sup) => sub :<: sup
- inject :: g :<: f => g (Free f a) -> Free f a
- class Run a b where
  - runAlgebra :: b (a v) -> a v
- run :: (Functor f, Monad b, Run b f) => Wizard f a -> b (Maybe a)
- data Output w = Output String w
- data OutputLn w = OutputLn String w
- data Line w = Line PromptString (String -> w)
- data LinePrewritten w = LinePrewritten PromptString String String (String -> w)
- data Password w = Password PromptString (Maybe Char) (String -> w)
- data Character w = Character PromptString (Char -> w)
- data ArbitraryIO w = forall a. ArbitraryIO (IO a) (a -> w)

# Documentation

newtype Wizard backend a Source #

A `Wizard b a` is a conversation with the user via back-end `b` that will result in a data type `a`, or may fail. A `Wizard` is made up of one or more "primitives" (see below), composed using the `Applicative`, `Monad` and `Alternative` instances. The `Alternative` instance is, as you might expect, a maybe-style cascade. If the first wizard fails, the next one is tried. `mzero` can be used to induce failure directly.

The `Wizard` constructor is exported here for use when developing backends, but it is better for end-users to simply pretend that `Wizard` is an opaque data type. Don't depend on this unless you have no other choice.

`Wizard`s are, internally, just a maybe transformer over a free monad built from some coproduct of functors, each of which is a primitive action.

Constructors

Wizard (MaybeT (Free backend) a) |

#### Instances

Instances details

ArbitraryIO :<: b => MonadIO (Wizard b) Source # |
Instance details Defined in System.Console.Wizard Methods liftIO :: IO a -> Wizard b a Source #
Functor backend => Alternative (Wizard backend) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods empty :: Wizard backend a Source # (<|>) :: Wizard backend a -> Wizard backend a -> Wizard backend a Source # some :: Wizard backend a -> Wizard backend [a] Source # many :: Wizard backend a -> Wizard backend [a] Source #
Functor backend => Applicative (Wizard backend) Source # |

Instance details

Defined in System.Console.Wizard.Internal

Methods

pure :: a -> Wizard backend a Source #

(<*>) :: Wizard backend (a -> b) -> Wizard backend a -> Wizard backend b Source #

liftA2 :: (a -> b -> c) -> Wizard backend a -> Wizard backend b -> Wizard backend c Source #

(*>) :: Wizard backend a -> Wizard backend b -> Wizard backend b Source #

(<*) :: Wizard backend a -> Wizard backend b -> Wizard backend a Source #

Functor backend => Functor (Wizard backend) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> Wizard backend a -> Wizard backend b Source # (<$) :: a -> Wizard backend b -> Wizard backend a Source #
Functor backend => Monad (Wizard backend) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods (>>=) :: Wizard backend a -> (a -> Wizard backend b) -> Wizard backend b Source # (>>) :: Wizard backend a -> Wizard backend b -> Wizard backend b Source # return :: a -> Wizard backend a Source #
Functor backend => MonadPlus (Wizard backend) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods mzero :: Wizard backend a Source # mplus :: Wizard backend a -> Wizard backend a -> Wizard backend a Source #

type PromptString = String Source #

A string for a prompt

data (f :+: g) w infixr 9 Source #

Coproduct of two functors

Constructors

Inl (f w) |
Inr (g w) |

#### Instances

Instances details

(Functor f, Functor g) => f :<: (f :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods inj :: f a -> (f :+: g) a
(Functor f, Functor g, Functor h, f :<: g) => f :<: (h :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods inj :: f a -> (h :+: g) a
(Run b f, Run b g) => Run b (f :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods runAlgebra :: (f :+: g) (b v) -> b v Source #
(Functor f, Functor g) => Functor (f :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> (f :+: g) a -> (f :+: g) b Source # (<$) :: a -> (f :+: g) b -> (f :+: g) a Source #

class (Functor sub, Functor sup) => sub :<: sup Source #

Subsumption of two functors. You shouldn't define any of your own instances of this when writing back-ends, rely only on GeneralizedNewtypeDeriving.

Minimal complete definition

inj

#### Instances

Instances details

WithSettings :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: WithSettings a -> Haskeline a
ArbitraryIO :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: ArbitraryIO a -> BasicIO a
ArbitraryIO :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: ArbitraryIO a -> Haskeline a
Character :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Character a -> BasicIO a
Character :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Character a -> Haskeline a
Character :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Character a -> Pure a
Line :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Line a -> BasicIO a
Line :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Line a -> Haskeline a
Line :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Line a -> Pure a
LinePrewritten :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: LinePrewritten a -> Haskeline a
Output :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Output a -> BasicIO a
Output :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Output a -> Haskeline a
Output :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Output a -> Pure a
OutputLn :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: OutputLn a -> BasicIO a
OutputLn :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: OutputLn a -> Haskeline a
OutputLn :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: OutputLn a -> Pure a
Password :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Password a -> Haskeline a
Functor f => f :<: f Source # |
Instance details Defined in System.Console.Wizard.Internal Methods inj :: f a -> f a
(Functor f, Functor g) => f :<: (f :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods inj :: f a -> (f :+: g) a
(Functor f, Functor g, Functor h, f :<: g) => f :<: (h :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods inj :: f a -> (h :+: g) a

inject :: g :<: f => g (Free f a) -> Free f a Source #

Injection function for free monads, see "Data Types a la Carte" from Walter Swierstra, `http://www.cs.ru.nl/~W.Swierstra/Publications/DataTypesALaCarte.pdf`

class Run a b where Source #

A class for implementing actions on a backend. E.g Run IO Output provides an interpreter for the Output action in the IO monad.

Methods

runAlgebra :: b (a v) -> a v Source #

#### Instances

Instances details

Run IO BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: BasicIO (IO v) -> IO v Source #
Run IO ArbitraryIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: ArbitraryIO (IO v) -> IO v Source #
Run IO Character Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Character (IO v) -> IO v Source #
Run IO Line Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Line (IO v) -> IO v Source #
Run IO Output Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Output (IO v) -> IO v Source #
Run IO OutputLn Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: OutputLn (IO v) -> IO v Source #
(Run b f, Run b g) => Run b (f :+: g) Source # |
Instance details Defined in System.Console.Wizard.Internal Methods runAlgebra :: (f :+: g) (b v) -> b v Source #
Run (InputT IO) Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Haskeline (InputT IO v) -> InputT IO v Source #
Run (InputT IO) WithSettings Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: WithSettings (InputT IO v) -> InputT IO v Source #
Run (InputT IO) ArbitraryIO Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: ArbitraryIO (InputT IO v) -> InputT IO v Source #
Run (InputT IO) Character Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Character (InputT IO v) -> InputT IO v Source #
Run (InputT IO) Line Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Line (InputT IO v) -> InputT IO v Source #
Run (InputT IO) LinePrewritten Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: LinePrewritten (InputT IO v) -> InputT IO v Source #
Run (InputT IO) Output Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Output (InputT IO v) -> InputT IO v Source #
Run (InputT IO) OutputLn Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: OutputLn (InputT IO v) -> InputT IO v Source #
Run (InputT IO) Password Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Password (InputT IO v) -> InputT IO v Source #
Run (State PureState) Character Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Character (State PureState v) -> State PureState v Source #
Run (State PureState) Line Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Line (State PureState v) -> State PureState v Source #
Run (State PureState) Output Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Output (State PureState v) -> State PureState v Source #
Run (State PureState) OutputLn Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: OutputLn (State PureState v) -> State PureState v Source #
Run (State PureState) Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Pure (State PureState v) -> State PureState v Source #

run :: (Functor f, Monad b, Run b f) => Wizard f a -> b (Maybe a) Source #

Run a wizard using some back-end.

Each of the following functors is a primitive action. A back-end provides interpreters for these actions using the `Run` class,

data Output w Source #

Constructors

Output String w |

#### Instances

Instances details

Functor Output Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> Output a -> Output b Source # (<$) :: a -> Output b -> Output a Source #
Output :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Output a -> BasicIO a
Output :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Output a -> Haskeline a
Output :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Output a -> Pure a
Run IO Output Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Output (IO v) -> IO v Source #
Run (InputT IO) Output Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Output (InputT IO v) -> InputT IO v Source #
Run (State PureState) Output Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Output (State PureState v) -> State PureState v Source #

data OutputLn w Source #

Constructors

OutputLn String w |

#### Instances

Instances details

Functor OutputLn Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> OutputLn a -> OutputLn b Source # (<$) :: a -> OutputLn b -> OutputLn a Source #
OutputLn :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: OutputLn a -> BasicIO a
OutputLn :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: OutputLn a -> Haskeline a
OutputLn :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: OutputLn a -> Pure a
Run IO OutputLn Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: OutputLn (IO v) -> IO v Source #
Run (InputT IO) OutputLn Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: OutputLn (InputT IO v) -> InputT IO v Source #
Run (State PureState) OutputLn Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: OutputLn (State PureState v) -> State PureState v Source #

data Line w Source #

Constructors

Line PromptString (String -> w) |

#### Instances

Instances details

Functor Line Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> Line a -> Line b Source # (<$) :: a -> Line b -> Line a Source #
Line :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Line a -> BasicIO a
Line :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Line a -> Haskeline a
Line :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Line a -> Pure a
Run IO Line Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Line (IO v) -> IO v Source #
Run (InputT IO) Line Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Line (InputT IO v) -> InputT IO v Source #
Run (State PureState) Line Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Line (State PureState v) -> State PureState v Source #

data LinePrewritten w Source #

Constructors

LinePrewritten PromptString String String (String -> w) |

#### Instances

Instances details

Functor LinePrewritten Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> LinePrewritten a -> LinePrewritten b Source # (<$) :: a -> LinePrewritten b -> LinePrewritten a Source #
LinePrewritten :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: LinePrewritten a -> Haskeline a
Run (InputT IO) LinePrewritten Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: LinePrewritten (InputT IO v) -> InputT IO v Source #

data Password w Source #

Constructors

Password PromptString (Maybe Char) (String -> w) |

#### Instances

Instances details

Functor Password Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> Password a -> Password b Source # (<$) :: a -> Password b -> Password a Source #
Password :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Password a -> Haskeline a
Run (InputT IO) Password Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Password (InputT IO v) -> InputT IO v Source #

data Character w Source #

Constructors

Character PromptString (Char -> w) |

#### Instances

Instances details

Functor Character Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> Character a -> Character b Source # (<$) :: a -> Character b -> Character a Source #
Character :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: Character a -> BasicIO a
Character :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: Character a -> Haskeline a
Character :<: Pure Source # |
Instance details Defined in System.Console.Wizard.Pure Methods inj :: Character a -> Pure a
Run IO Character Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: Character (IO v) -> IO v Source #
Run (InputT IO) Character Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: Character (InputT IO v) -> InputT IO v Source #
Run (State PureState) Character Source # |
Instance details Defined in System.Console.Wizard.Pure Methods runAlgebra :: Character (State PureState v) -> State PureState v Source #

data ArbitraryIO w Source #

Constructors

forall a. ArbitraryIO (IO a) (a -> w) |

#### Instances

Instances details

Functor ArbitraryIO Source # |
Instance details Defined in System.Console.Wizard.Internal Methods fmap :: (a -> b) -> ArbitraryIO a -> ArbitraryIO b Source # (<$) :: a -> ArbitraryIO b -> ArbitraryIO a Source #
ArbitraryIO :<: BasicIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods inj :: ArbitraryIO a -> BasicIO a
ArbitraryIO :<: Haskeline Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods inj :: ArbitraryIO a -> Haskeline a
Run IO ArbitraryIO Source # |
Instance details Defined in System.Console.Wizard.BasicIO Methods runAlgebra :: ArbitraryIO (IO v) -> IO v Source #
Run (InputT IO) ArbitraryIO Source # |
Instance details Defined in System.Console.Wizard.Haskeline Methods runAlgebra :: ArbitraryIO (InputT IO v) -> InputT IO v Source #

A short tutorial on writing backends.

Backends consist of two main components:

1. A monad, `M`, in which the primitive actions are interpreted. `Run` instances specify an interpreter for each supported action, e.g `Run M Output` will specify an interpreter for the `Output` primitive action in the monad M.
2. A newtype, e.g `Backend a`, which is a functor, usually implemented by wrapping a coproduct of all supported features. `(:<:)` instances, the `Functor` instance, and the `Run` instance are provided by generalized newtype deriving.

As an example, suppose I am writing a back-end to `IO`, like System.Console.Wizard.BasicIO. I want to support basic input and output, and arbitrary IO, so I declare instances for `Run` for the `IO` monad:

     instance Run IO Output      where runAlgebra (Output s w)        = putStr s   >> w
     instance Run IO OutputLn    where runAlgebra (OutputLn s w)      = putStrLn s >> w
     instance Run IO Line        where runAlgebra (Line s w)          = getLine    >>= w
     instance Run IO Character   where runAlgebra (Character s w)     = getChar    >>= w
     instance Run IO ArbitraryIO where runAlgebra (ArbitraryIO iov f) = iov        >>= f

And then I would define the newtype for the backend, which we can call `MyIOBackend`:

     newtype MyIOBackend a = MyIOBackend ((Output :+: OutputLn :+: Line :+: Character :+: ArbitraryIO) a)
                           deriving ( Functor, Run IO
                                    , (:<:) Output
                                    , (:<:) OutputLn
                                    , (:<:) Line
                                    , (:<:) Character
                                    , (:<:) ArbitraryIO
                                    )

A useful convenience is to provide a simple identity function to serve as a type coercion:

     myIOBackend :: Wizard MyIOBackend a -> Wizard MyIOBackend a
     myIOBackend = id

One additional primitive action that I might want to include is the ability to clear the screen at a certain point. So, we define a new data type for the action:

     data ClearScreen w = ClearScreen w deriving Functor -- via -XDeriveFunctor

And a "smart" constructor for use by the user:

     clearScreen :: (ClearScreen :<: b) => Wizard b ()
     clearScreen = Wizard $ lift $ inject (ClearScreen (Pure ()))

(These smart constructors all follow a similar pattern. See the source of System.Console.Wizard for more examples)

And then we define an interpreter for it:

     instance Run IO ArbitraryIO where runAlgebra (ClearScreen f) = clearTheScreen >> f

Now, we can use this as-is simply by directly extending our back-end:

     foo :: Wizard (ClearScreen :+: MyIOBackend)
     foo = clearScreen >> output "Hello World!"

Or, we could modify `MyIOBackend` to include the extension directly.

For custom actions that return output, the definition looks slightly different. Here is the definition of Line:

     data Line w = Line (PromptString) (String -> w) deriving Functor -- via -XDeriveFunctor

And the smart constructor looks like this:

     line :: (Line :<: b) => PromptString -> Wizard b String
     line s = Wizard $ lift $ inject (Line s Pure)