-
Notifications
You must be signed in to change notification settings - Fork 100
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).
// 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.
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