applicative-splice- Write applicative programs in direct style (generalizes idiom brackets).

Safe HaskellNone



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)

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 Source

The applicative-splice quasiquoter.