stm-incremental: A library for constructing incremental computations

[ concurrency, control, library, mit ] [ Propose Tags ]

A library for constructing incremental computations.

[Skip to Readme]


[Index] [Quick Jump]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS],,,
Change log
Dependencies base (>=4.12 && <5), stm (>=2.1) [details]
License MIT
Copyright 2019 Samuel Schlesinger
Author Samuel Schlesinger
Category Control, Concurrency
Home page
Bug tracker
Source repo head: git clone
Uploaded by sgschlesinger at 2023-02-02T05:57:26Z
Distributions NixOS:
Downloads 418 total (4 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2023-02-02 [all 1 reports]

Readme for stm-incremental-

[back to package description]



This library is meant to expose an interface for incremental computation using software transactional memory in Haskell.

import Control.Concurrent.STM.Incremental

main = do
  (salutation, name, greeting) <- atomically do
    salutation <- incremental "Hello"
    name <- incremental "Samuel"
    greeting <- combine (\s n -> s <> ", " n) salutation name
    pure (salutation, name, greeting)
  -- Will print "Hello, Samuel"
  atomically (observe greeting) >>= print
  atomically (set salutation "Hiya")
  -- Will print "Hiya, Samuel"
  atomically (observe greeting) >>= print

There are three operations, imap, combine, and choose. They sort of correspond to the operations of fmap, liftA2, and (>>=), but not exactly. imap allows you to construct an incremental computation depending on one other, which only ever gets updated when this single dependency does. combine allows you to construct an incremental computation depending on two others, which gets updated whenever either does. choose allows you to switch your dependency structure depending on live values in the incremental computation. In other words, this allows you to have dynamic dependencies, whereas the former two functions only allowed you to have static dependencies.

The choose combinator is the most computationally expensive, requiring in the worst case time proportional to the size of the image of the choice function passed in.