each: Template Haskell library for writing monadic expressions more easily

[ bsd3, language, library ] [ Propose Tags ]

See README at the bottom.

Getting started: See Each.

[Skip to Readme]
Versions [faq],,
Dependencies base (>=4.9 && <5), containers (>=, mtl (>=2.2.1), template-haskell (>= [details]
License BSD-3-Clause
Copyright (C) dramforever <dramforever@live.com>
Author dramforever
Maintainer dramforever@live.com
Category Language
Home page https://github.com/dramforever/each#readme
Source repo head: git clone https://github.com/dramforever/each
Uploaded by dramforever at Sun Feb 5 14:34:17 UTC 2017
Distributions NixOS:
Downloads 1033 total (48 in the last 30 days)
Rating 2.25 (votes: 2) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2017-02-05 [all 1 reports]




Maintainer's Corner

For package maintainers and hackage trustees

Readme for each-

[back to package description]


Inspired by the Scala library of the same name, each is a Template Haskell library that transforms expressions containing invocations of impure subexpressions into calls to fmap, <*>, join, etc. Just mark your impure subexpressions with bind or ~! and they will be called appropriately, as in this small demo:

ghci> $(each [| "Hello, " ++ (~! getLine) |])
World              <--[keyboard input]
"Hello, World"

In this case, the code is translated into fmap ((++) "Hello, ") getLine

We currently have support for

  • Normal function application like f x y
  • Infix operator application like x + y, including sections like (+ y)
  • Type signatures like x :: t

Support for more constructs is coming.

More demos

A more detailed demo:

ghci> :{
    | $(each [|
    |   "Hey it works"
    |   ++ show (length $
    |     "something"
    |     ++ (~! readFile "/etc/issue")
    |     ++ (~! readFile "/etc/issue.net"))
    | |])
    | :}
"Hey it works64"

Nested binds also work as expected.

ghci> prompt str = putStrLn str *> getLine
ghci> $(each [| "Nah just " ++ (~! prompt ("What's " ++ bind getLine ++ "?")) |])
something          <--[keyboard input]
What's something?
nothing            <--[keyboard input]
"Nah just nothing"