All Projects → tweag → Capability

tweag / Capability

Licence: bsd-3-clause
Extensional capabilities and deriving combinators

Programming Languages

haskell
3896 projects

Labels

Projects that are alternatives of or similar to Capability

Managedbass
.Net Wrapper for 'Bass' Audio Library
Stars: ✭ 131 (-25.57%)
Mutual labels:  effects
Enviews
🌟A cool dynamic view library
Stars: ✭ 1,771 (+906.25%)
Mutual labels:  effects
Unityskidmarks
A simple skidmark effect generator for Unity3D
Stars: ✭ 165 (-6.25%)
Mutual labels:  effects
Jamesdspmanager
Audio DSP effects build on Android system framework layer. This is a repository contains a pack of high quality DSP algorithms specialized for audio processing.
Stars: ✭ 136 (-22.73%)
Mutual labels:  effects
Lawvere
A categorical programming language with effects
Stars: ✭ 142 (-19.32%)
Mutual labels:  effects
Algebraic Effects
Manage side-effects in your javascript application cleanly with algebraic effects
Stars: ✭ 162 (-7.95%)
Mutual labels:  effects
Effection
Effortlessly composable structured concurrency primitive for JavaScript
Stars: ✭ 120 (-31.82%)
Mutual labels:  effects
Raj
The Elm Architecture for JavaScript
Stars: ✭ 169 (-3.98%)
Mutual labels:  effects
Learnunityshader
学习Unity Shader过程中的一些记录,特效,动画Demo。
Stars: ✭ 141 (-19.89%)
Mutual labels:  effects
Threejs Sandbox
Set of experiments and extensions to THREE.js.
Stars: ✭ 163 (-7.39%)
Mutual labels:  effects
Baffects.js
Baffects.js is a library adaptation in JavaScript for Adobe After Effects of the Processing language. It allows for most of the functionality included in Processing to be used natively in After Effects, plus a custom workflow to enhance productivity in After Effects.
Stars: ✭ 141 (-19.89%)
Mutual labels:  effects
Magick.net
The .NET library for ImageMagick
Stars: ✭ 2,071 (+1076.7%)
Mutual labels:  effects
Guitarstack
Digital guitar effects right in your browser!
Stars: ✭ 164 (-6.82%)
Mutual labels:  effects
React Navigation Magic Move
Bindings for using react-navigation with react-native-magic-move 🐰🎩✨
Stars: ✭ 132 (-25%)
Mutual labels:  effects
Toucheffects
Android View点击特效TouchEffects,几行代码为所有控件添加点击效果
Stars: ✭ 167 (-5.11%)
Mutual labels:  effects
Shurikenplus
A collection of custom shaders for Unity particle system (Shuriken).
Stars: ✭ 121 (-31.25%)
Mutual labels:  effects
Normalmap.js
normalmap.js is a library for creating simple interactive lighting effects using normal maps.
Stars: ✭ 156 (-11.36%)
Mutual labels:  effects
View Effects
Apply custom effects on view backgrounds
Stars: ✭ 176 (+0%)
Mutual labels:  effects
Extensible Effects
Extensible Effects: An Alternative to Monad Transformers
Stars: ✭ 167 (-5.11%)
Mutual labels:  effects
Ddc
The Disco Discus Compiler
Stars: ✭ 164 (-6.82%)
Mutual labels:  effects

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) 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) 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"
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].