The each package


See README at the bottom.

Getting started: See Each.

[Skip to ReadMe]


Dependenciesbase (>=4.9 && <5), dlist (>=, template-haskell (>= [details]
Copyright(C) dramforever <>
Home page
Source repositoryhead: git clone
UploadedMon Feb 6 15:18:11 UTC 2017 by dramforever




Maintainers' corner

For package maintainers and hackage trustees

Readme for each-


Inspired by the Scala library of the same name, each is a Template Haskell library that transforms expressions containing invocations of impure subexpressions into do-notation. 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"

With the ApplicativeDo GHC extension, calls to fmap and <*> will be arranged so that you don't need to worry if you use, say, Haxl and needs Applicative for parallelism.

Most constructs where this would make things much more simpler are already supported. In particular, these are okay:

These are some quirks:

If you find something wrong, or really want some feature, feel free to leave an issue.

How it works

The basic structure of an each block is this:

$(each [| ... |])

Inside of this block, three (interchangable) ways are used to mark impure subexpressions:

do-notation is generated according to left-to-right order, and branching is handled.

More demos

A more detailed demo:

ghci> :{
    | $(each [|
    |   "Hey it works"
    |   ++ show (length $
    |     "something"
    |     ++ (~! readFile "/etc/issue")
    |     ++ (~! readFile "/etc/"))
    | |])
    | :}
"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"