Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/iokasimov/joint
Extremely simple effect system for Haskell
https://github.com/iokasimov/joint
effects transformers
Last synced: 22 days ago
JSON representation
Extremely simple effect system for Haskell
- Host: GitHub
- URL: https://github.com/iokasimov/joint
- Owner: iokasimov
- License: bsd-3-clause
- Created: 2018-06-23T19:44:17.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-01-06T05:17:21.000Z (almost 4 years ago)
- Last Synced: 2024-04-23T17:32:33.534Z (7 months ago)
- Topics: effects, transformers
- Language: Haskell
- Homepage:
- Size: 153 KB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Extremely simple effect system for Haskell
[Hackage documentation](http://hackage.haskell.org/package/joint) | [Examples](https://github.com/iokasimov/experiments)
## Overview
`joint` let you type expressions by effects that they produce. No free/freer monad, no GADTs and other fancy stuff - all you need is a functor composition. If you want to be able to use your on effect in this library you need to pick a `joint schema` and write several instances (`Functor`/`Applicative`/`Monad`). For better understanding it's recommend to read this explanation series: [part 1](https://iokasimov.github.io/posts/2019/11/joint), [part 2](https://iokasimov.github.io/posts/2020/02/joint), [part 3](https://iokasimov.github.io/posts/2021/01/composable-monad-transformers).
## Simple real world example
Let’s imagine that we need to make an HTTP request, it’s `IO`, that can throw `HttpException`:
```haskell
import qualified "wreq" Network.Wreq as HTTPrequest :: (Monad t, Liftable IO t, Failable HttpException t) => t (Response ByteString)
request = lift (try @HttpException $ HTTP.get link) >>= lift
```Wow, what is there? First, we `lift` some `IO`-action, then after `>>=` we `lift` `Either` and we get an expression, that can be used in many effectful expressions than contain such two effects! We can delay using concrete transformers until we really need to evaluate them.
## Composing lifted effects
If you have some effectful expression, you can easy compose them:
```haskell
let f = get :: Configured _ t => t _
let g = nothing :: Optional t => t _
let h = failure _ :: Failable _ t => t _let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _
```## Fit effects in transformers
If you have concrete transformers, the order of effects doesn't matter, you can fit lifted effects to them:
```haskell
let y = pure _ :: Reader _ :> State _ :> Either _ :> Maybe := Int
let z = pure _ :: State _ :> Either _ :> Maybe _ :> Reader := _let x = f *> g *> h :: (Applicative t, Configured _ t, Optional t, Failable _ t) => t _
let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _
let xz = x *> z :: State _ :> Either _ :> Maybe _ :> Reader := _
```## Running effects in transfomers
To interpret some effect you can use `run` method:
```haskell
let xy = x *> y :: Reader _ :> State _ :> Either _ :> Maybe := _
let xy' = run xy _ :: State _ :> Either _ :> Maybe := _
let xy'' = run xy' _ :: Either _ :> Maybe := _
let xy''' = run xy'' :: Maybe (Either _) _
```