Add local function to Reader and ReaderT
- Dominant language
- JavaScript
- Stars
- 1.6k
- Forks
- 103
- PR merge metrics
- No merged PRs in 30d
Description
**Is your feature request related to a problem? Please describe.**
In Haskell the Reader monad has a function called `local` that let's you to temporarily modify the environment used by the monad. This is really useful when you want to pass the results of a previous call to functions later on in the computation.
**Describe the solution you'd like**
I would like to Crocks to implement the `local` function as per Haskell. Interesting this just appears to be `contramap` but the Haskell implementation is still called `local` for some reason. I am happy to work on a PR for this if there's an appetite to add this function.
**Describe alternatives for how you do this now**
I toyed with the idea of nesting ReaderT monads but this solution is much cleaner
**Code**
I don't have a REPL but have already got this working locally and it was very easy (I basically just translated from Haskell).
```js
// Reader
function local(method) {
return function(fn) {
if(!isFunction(fn)) {
throw new TypeError(("Reader." + method + ": Function required"))
}
return Reader(e => runWith(fn(e)))
}
}
// ReaderT
function local(fn) {
if(!isFunction(fn)) {
throw new TypeError(((type()) + ".map: Function required"))
}
return ReaderT(function (e) { return runWith(fn(e)) })
}
```
To use it's very simple.
```js
const {Async, ReaderT} = require('crocks');
const ReaderAsync = ReaderT(Async);
// localFunc :: String -> ReaderT e (Async a b)
function localFunc(paramToAdd) {
return func1() // returns a ReaderAsync
.chain(func2) // function requires paramToAdd to be in env
.chain(func3) // function requires paramToAdd to be in env
.local(e => ({y: paramToAdd, ...e}) // previous 3 functions will use modified env
.map(func4) // will use unmodified env
}
getParamToAdd()
.chain(localFunc)
.map(func5)
// ...
.runWith({x: 'param'})
.fork(/* ... */)
```
Here's some real code that uses this new function if you want something more interesting than the above contrived example:
https://github.com/svozza/functionalish-refactor/blob/master/functional/lib/index.js
Contributor guide
Assessment
This issue has not been assessed yet.