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

System.Console.Wizard.Internal

Synopsis

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.

Wizards 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) 
Instance details

Defined in System.Console.Wizard

Methods

liftIO :: IO a -> Wizard b a

Functor backend => Alternative (Wizard backend) Source # 
Instance details

Defined in System.Console.Wizard.Internal

Methods

empty :: Wizard backend a

(<|>) :: Wizard backend a -> Wizard backend a -> Wizard backend a

some :: Wizard backend a -> Wizard backend [a]

many :: Wizard backend a -> Wizard backend [a]

Functor backend => Applicative (Wizard backend) Source # 
Instance details

Defined in System.Console.Wizard.Internal

Methods

pure :: a -> Wizard backend a

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

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

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

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

Functor backend => Functor (Wizard backend) Source # 
Instance details

Defined in System.Console.Wizard.Internal

Methods

fmap :: (a -> b) -> Wizard backend a -> Wizard backend b

(<$) :: a -> Wizard backend b -> Wizard backend a

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

(>>) :: Wizard backend a -> Wizard backend b -> Wizard backend b

return :: a -> Wizard backend a

Functor backend => MonadPlus (Wizard backend) Source # 
Instance details

Defined in System.Console.Wizard.Internal

Methods

mzero :: Wizard backend a

mplus :: Wizard backend a -> Wizard backend a -> Wizard backend a

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

(<$) :: a -> (f :+: g) b -> (f :+: g) a

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

(<$) :: a -> Output b -> Output 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

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

(<$) :: a -> OutputLn b -> OutputLn 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

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

(<$) :: a -> Line b -> Line 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

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

(<$) :: a -> LinePrewritten b -> LinePrewritten a

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

(<$) :: a -> Password b -> Password a

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

(<$) :: a -> Character b -> Character 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

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

(<$) :: a -> ArbitraryIO b -> ArbitraryIO 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

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)