Safe Haskell | None |
---|---|

Language | Haskell2010 |

This module defines a quasiquoter for making it easier to program with applicatives and monads.

# Basic usage

The `appl`

quasiquoter takes almost any Haskell expression, and expands to the
same Haskell expression, wrapped in a call to `pure`

. For example,

[appl| 4 + 5 |] -- expands to: pure (4 + 5)

Additionally, the expression given to `appl`

may contain "splices". A splice
is a dollar sign immediately followed by a parenthesized expression.
The parentheses can be dropped if the expression consists of a single
identifier. Here are examples of splices.

$(f a b) $([0..7]) $getLine

The syntax for splices are stolen from Template Haskell splices. Therefore whitespaces are not allowed after the dollar sign.

The expression inside a splice should have the type `f a`

for some
`Applicative`

`f`

and some type `a`

. The splice itself should be
placed in a context where a value of type `a`

is expected. Then `appl`

expands
to an applicative expression that "embeds" the result of the applicative
action in the pure context. For example,

[appl| f $x (4 + $y) |] -- expands to: (\a b -> f a (4 + b)) <$> x <*> y

In terms of types, the dollar sign is like a function of type `forall a. f a -> a`

,
although it is not a real function.

The type of the `appl`

expression will be in the same applicative as the
splices. This also means mutliple splices in the same block must
share the same applicative.

# Special case: functor splices

When an `appl`

block contains exactly one splice, the type of the expression
inside the splice can be `f a`

for any functor `f`

, and it doesn't have to be
an applicative. The expansion will only contain a call to `<$>`

, not `pure`

or `<*>`

.

[appl| ("Length", length $m) |] -- expands to: (\a -> ("Length", length a)) <$> m

# Nested splices for monads

When your applicative is also a monad, you can have splices inside another splice. For example,

[appl| $(putStrLn $ "Hello, " ++ $getLine) |] -- expands to: getLine >>= (\a -> putStrLn $ "Hello, " ++ a)

As in this case, no call to `<$>`

is generated if the whole `appl`

block
consists of a single splice.

- appl :: QuasiQuoter

# Documentation

The applicative-splice quasiquoter.