• Stars
    star
    214
  • Rank 179,119 (Top 4 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created almost 6 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Extensional capabilities and deriving combinators

capability: effects, extensionally

Build status

A capability is a type class that says explicitly which effects a function is allowed to use. The mtl works like this too. But unlike the mtl, this library decouples effects from their implementation. What this means in practice:

  • You can implement large sets of capabilities using the efficient ReaderT pattern, rather than a slow monad transformer stack.
  • Capabilities compose well: e.g. it's easy to have multiple reader effects.
  • You can use a writer effect without implementing it as a writer monad (which is known to leak space).
  • You can reason about effects. For instance, if a monad provides a reader effect at type IORef A, it also provides a state effect at type A

For more on these, you may want to read the announcement blog post.

This library is an alternative to the mtl. It defines a set of standard, reusable capability type classes, such as the HasReader and HasState type classes, which provide the standard reader and state effects, respectively.

Where mtl instances only need to be defined once and for all, capability-style programming has traditionally suffered from verbose boilerplate: rote instance definitions for every new implementation of the capability. Fortunately GHC 8.6 introduced the DerivingVia language extension. We use it to remove the boilerplate, turning capability-style programming into an appealing alternative to mtl-style programming. The generic-lens library is used to access fields of structure in the style of the ReaderT pattern.

An additional benefit of separating capabilities from their implementation is that they avoid a pitfall of the mtl. In the mtl, two different MonadState are disambiguated by their types, which means that it is difficult to have two MonadState Int in the same monad stack. Capability type classes are parameterized by a name (also known as a tag). This makes it possible to combine multiple versions of the same capability. For example,

twoStates :: (HasState "a" Int m, HasState "b" Int m) => m ()

Here, the tags "a" and "b" refer to different state spaces.

In summary, compared to the mtl:

  • capabilities represent what effects a function can use, rather than how the monad is constructed;
  • capabilities are named, rather than disambiguated by type;
  • capabilites are discharged with deriving-via combinators and generic-lens, rather than with instance resolution.

An example usage looks like this:

testParity :: (HasReader "foo" Int m, HasState "bar" Bool m) => m ()
testParity = do
  num <- ask @"foo"
  put @"bar" (even num)

data Ctx = Ctx { foo :: Int, bar :: IORef Bool }
  deriving Generic

newtype M a = M { runM :: Ctx -> IO a }
  deriving (Functor, Applicative, Monad) via ReaderT Ctx IO
  -- Use DerivingVia to derive a HasReader instance.
  deriving (HasReader "foo" Int, HasSource "foo" Int) via
    -- Pick the field foo from the Ctx record in the ReaderT environment.
    Field "foo" "ctx" (MonadReader (ReaderT Ctx IO))
  -- Use DerivingVia to derive a HasState instance.
  deriving (HasState "bar" Bool, HasSource "bar" Bool, HasSink "bar" Bool) via
    -- Convert a reader of IORef to a state capability.
    ReaderIORef (Field "bar" "ctx" (MonadReader (ReaderT Ctx IO)))

example :: IO ()
example = do
    rEven <- newIORef False
    runM testParity (Ctx 2 rEven)
    readIORef rEven >>= print
    runM testParity (Ctx 3 rEven)
    readIORef rEven >>= print

For more complex examples, see the Examples section and the examples subtree.

API documentation can be found on Hackage.

Examples

An example is provided in WordCount. Execute the following commands to try it out:

$ nix-shell --pure --run "cabal configure --enable-tests"
$ nix-shell --pure --run "cabal repl examples"

ghci> :set -XOverloadedStrings
ghci> wordAndLetterCount "ab ba"
Letters
'a': 2
'b': 2
Words
"ab": 1
"ba": 1

To execute all examples and see if they produce the expected results run

$ nix-shell --pure --run "cabal test examples --show-details=streaming --test-option=--color"

Build instructions

Nix Shell

A development environment with all dependencies in scope is defined in shell.nix.

Build

The build instructions assume that you have Nix installed. Execute the following command to build the library.

$ nix-shell --pure --run "cabal configure"
$ nix-shell --pure --run "cabal build"

More Repositories

1

nickel

Better configuration for less
Rust
2,061
star
2

asterius

DEPRECATED in favor of ghc wasm backend, see https://www.tweag.io/blog/2022-11-22-wasm-backend-merged-in-ghc
Haskell
1,980
star
3

ormolu

A formatter for Haskell source code
Haskell
926
star
4

jupyenv

Declarative and reproducible Jupyter environments - powered by Nix
Nix
601
star
5

HaskellR

The full power of R in Haskell.
Haskell
578
star
6

topiary

Rust
486
star
7

sparkle

Haskell on Apache Spark.
Haskell
444
star
8

awesome-learning-haskell

A collection of resources which were useful to Tweagers for learning Haskell and its various aspects
399
star
9

monad-bayes

A library for probabilistic programming in Haskell.
Jupyter Notebook
395
star
10

funflow

Functional workflows
Haskell
361
star
11

linear-base

Standard library for linear types in Haskell.
Haskell
333
star
12

rules_nixpkgs

Rules for importing Nixpkgs packages into Bazel.
Starlark
262
star
13

rules_haskell

Haskell rules for Bazel.
Starlark
260
star
14

inline-java

Haskell/Java interop via inline Java code in Haskell modules.
Haskell
228
star
15

FawltyDeps

Python dependency checker
Python
173
star
16

clodl

Turn dynamically linked ELF binaries and libraries into self-contained closures.
Starlark
152
star
17

inline-js

Call JavaScript from Haskell, and vice versa!
Haskell
128
star
18

opam-nix

Turn opam-based OCaml projects into Nix derivations
Nix
97
star
19

linear-types

Drafts, notes and resources for adding linear typing to GHC.
TeX
74
star
20

terraform-provider-nixos

Terraform provider for NixOS and NixOps
Go
70
star
21

nix-hour

Questions for the weekly Nix Hour
Nix
64
star
22

distributed-closure

Serializable closures for distributed programming.
Haskell
63
star
23

terraform-provider-secret

Terraform secret provider
Shell
62
star
24

nixtract

A CLI tool to extract the graph of derivations from a Nix flake.
Rust
59
star
25

tf-ncl

Terraform Configurations with Nickel
Rust
58
star
26

guides

Designing, programming and deploying, in style.
58
star
27

python-monorepo-example

Example of a python monorepo using pip, the poetry backend, and Pants
Python
50
star
28

servant-template

A modern template for a Servant
Haskell
47
star
29

kernmantle

Braiding extensible effects together in a pipeline/workflow of tasks
Haskell
47
star
30

pirouette

Language-generic workbench for building static analysis
Haskell
47
star
31

skyscope

A tool for visualising and exploring Bazel Skyframe graphs.
Haskell
45
star
32

rules_sh

Shell rules for Bazel
Starlark
40
star
33

nix_bazel_codelab

Nix+Bazel Codelab
Starlark
40
star
34

python-nix

Python-Nix FFI library using the new C API
Python
36
star
35

nix-ux

Nix UX improvements
Nix
36
star
36

blog-resources

Extra resources for Tweag's blog posts.
Jupyter Notebook
35
star
37

cooked-validators

Haskell
35
star
38

lagoon

Data centralization tool
Haskell
35
star
39

webauthn

A library for parsing and validating webauthn/fido2 credentials
Haskell
33
star
40

haskell-training

Material for Haskell training
Haskell
31
star
41

hyperion

A lab for future Criterion features.
Haskell
29
star
42

network-transport-zeromq

ZeroMQ transport for distributed-process (aka Cloud Haskell)
Haskell
22
star
43

haskell-stack-nix-example

Examples of valid and invalid Stack + Nix integration
Nix
20
star
44

genealogos

Genealogos, a Nix sbom generator
Rust
18
star
45

timestats

A library to profile time in a Haskell program
Haskell
17
star
46

ssh-participation

An ssh server that creates new users on-the-fly, great for letting users participate in a demo
Nix
15
star
47

nix_gazelle_extension

Gazelle language extension for nix files
Go
15
star
48

epcb

Nix RFC draft on evaluation purity and caching builtins
15
star
49

nixpkgs-graph-explorer

Explore the nixpkgs dependency graph
Python
14
star
50

nixpkgs-graph

Generate a graph from nixpkgs
Python
14
star
51

haskell-binaryen

Haskell bindings to binaryen.
WebAssembly
14
star
52

gazelle_cabal

A gazelle extension to produce Haskell rules from cabal files
Haskell
13
star
53

smtlib-backends

A Haskell library providing low-level functions for SMTLIB-based interaction with SMT solvers.
Haskell
13
star
54

rust-wasm-threads

Examples of Web Workers using rust and WASM
Rust
11
star
55

chainsail

Replica Exchange sampling as-a-service
Python
10
star
56

random-quality

Framework for testing quality of random number generators
Nix
10
star
57

rules_haskell_examples

Examples of using Bazel's Haskell rules.
9
star
58

funflow2

Compose and run computational workflows
Haskell
9
star
59

rust-wasm-nix

Nix
9
star
60

store-graph

simple haskell code that builds a graph from the nix store
Shell
9
star
61

purescript-unlift

MonadBase, MonadUnliftEffect, MonadUnliftAff, and MonadUnlift
Nix
9
star
62

stackage-head

Stackage builds based on GHC HEAD
Haskell
9
star
63

ghc-wasm-miso-examples

Haskell
9
star
64

nix-installer-generator

Nix installer generator
Nix
8
star
65

functionless

CLI tool for packaging Haskell executables for AWS Lambda
Java
8
star
66

ch-nixops-example

Example deployment of Cloud Haskell app using NixOps.
Haskell
8
star
67

nix-store-gcs-proxy

A HTTP nix store that proxies requests to Google Storage
Nix
8
star
68

ghc-wasm32-wasi

DEPRECATED, new home https://gitlab.haskell.org/ghc/ghc-wasm-meta
Nix
7
star
69

rust-alpine-mimalloc

Shell
7
star
70

python-nix-flake-template

Bootstrap a reproducible yet flexible Python development environment using Nix
Nix
7
star
71

terraform-gcp-cdn-bucket

A Google Storage Bucket + CDN configuration
HCL
7
star
72

servant-oauth2

A modern servant wrapper around the wai-middleware-auth OAuth2 provider implementations.
Haskell
7
star
73

hello-plutarch

Template project for smart-contracts in Plutarch
Nix
6
star
74

tendermint-bazel

Building Go with Bazel
Go
6
star
75

linear-constraints

TeX
6
star
76

ghc-asterius

DEPRECATED, new home https://gitlab.haskell.org/ghc/ghc
Haskell
6
star
77

remote-execution-nix

nix to bazel-re proxy
Rust
6
star
78

chainsail-resources

Examples, documentation and other additional resources related to Chainsail
Python
5
star
79

tf-ncl-examples

Examples of Terraform configuration with Nickel
NCL
5
star
80

nickel-lang.org

The website of the Nickel language
JavaScript
5
star
81

nix-marp

Run Marp tools via Nix
Nix
5
star
82

nickel-kubernetes

Typecheck, template and modularize your Kubernetes definitions with Nickel
Rust
5
star
83

duckling

a Haskell library that parses text into structured data
Haskell
4
star
84

graft

Haskell
4
star
85

nix-unit-testing

A showcase of different unit testing frameworks for Nix.
Python
4
star
86

rules_purescript

Python
4
star
87

summer-of-nix-modules

Incremental module system buildup for Summer of Nix
Nix
4
star
88

toronto_reproducibility_workshop

Slides and toy project for the talk at the Toronto Workshop on Reproducibility
Python
4
star
89

nixos-specialisation-dual-boot

Nix
4
star
90

inputs

Utilities for building forms with React
TypeScript
3
star
91

pthread

Bindings for the pthread library
Haskell
3
star
92

cooked-smart-contracts

Smart contracts for the Cardano blockchain written with Cooked-validators
Haskell
3
star
93

stack-docker-nix

Provision Haskell Stack Docker images using Nix
Dockerfile
3
star
94

organist-example

Python
3
star
95

zeromq4-haskell

Clone of the https://gitlab.com/twittner/zeromq-haskell
Haskell
3
star
96

gazelle_haskell_modules

A gazelle extension to generate haskell_module rules
Haskell
3
star
97

run-nix-shell

GitHub action for executing scripts via nix-shell.
Shell
3
star
98

economics

Data science focussed on economics and social science
Jupyter Notebook
2
star
99

smart-contracts-lh

Plutus smart contracts verified with Liquid Haskell
Haskell
2
star
100

ocaml-close

Transform 'open' in OCaml source files for optimal legibility
OCaml
2
star