Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
David Chambers
@davidchambers
Have you taken a peek at the sanctuary-type-classes pull request? I'm thrilled by how clean the dispatching logic is. Object-oriented programming is coming up trumps for a change!
Scott Christopher
@scott-christopher
I don't believe I have. I'll have to take a look.
It might be possible to create a bifunctor instance for the native Map too.
David Chambers
@davidchambers
Ah, okay. I think I'll leave out the native Map and Set types for now, but we could certainly support these in a later pull request.
Scott Christopher
@scott-christopher
Yeah it's a bit strange too, because you could arguably create something akin to a Profunctor for Map too, where the contravariant function modifies the argument provided to Map.prototype.get or Map.prototype.has before calling the underlying method
Do you care about Promises at all?
You could probably form a bifunctor over that.
David Chambers
@davidchambers
Very topical question. :stuck_out_tongue_winking_eye:
My answer is no (at least for now).
Scott Christopher
@scott-christopher
Yeah, I can't think of many other native types that would be represented with multiple type arguments.
David Chambers
@davidchambers
I'm pleased to learn there's at least one.
I'll define a Pair type in the test suite to give us a convenient type with which to test.
Scott Christopher
@scott-christopher
The common bifunctor types are usually Either/Coproduct, Tuple/Product and Const.
David Chambers
@davidchambers
That's helpful. Thanks, Scott!
Scott Christopher
@scott-christopher
No worries.
Just taking a look over the sanctuary-type-classes code now. It looks quite promising.
Scott Christopher
@scott-christopher
I think the chainRec implementation for Array might be a little off.
David Chambers
@davidchambers
Okay. It's a modified version of @safareli's gist. It's possible I botched some refactoring. It's also possible the gist is a little off.
What's wrong with it, do you think?
Scott Christopher
@scott-christopher

Something like:

function squash(next, done, a) {
  return Array.isArray(a) ? a.map(next) : [done(a)];
}

chainRec(squash, [1, [[2, 3], 4], 5]);

produces:

[1, [2, 3], 4, 5]

while I would have expected it to have been:

[1, 2, 3, 4, 5]
Due to the while (args.length > 0 && !args[0].done)
It does what I would have expected if it is modified to:
while (args.length > 0 && !args.every(prop('done')))
David Chambers
@davidchambers
Ah, okay. So it's not safe to assume that all args are in the same state.
Scott Christopher
@scott-christopher
Or if you'd prefer to not every over each iteration, it could be refactored to something like:
function chainRec(f, x) {
  var next = function(x) { return {value: x, done: false}; };
  var done = function(x) { return {value: x, done: true}; };
  var out = [];
  var todo = [x];
  while (todo.length > 0) {
    var xs = f(next, done, todo.shift());
    var partitioned = xs.reduce(function(acc, x) {
      var bucket = x.done ? acc[1] : acc[0];
      bucket.push(x.value);
      return acc;
    }, [[], []]);
    todo.unshift.apply(todo, partitioned[0]);
    out.push.apply(out, partitioned[1]);
  }
  return out;
}
David Chambers
@davidchambers
Oh, that's cool! Mind if I use your implementation instead?
Scott Christopher
@scott-christopher
By all means, but please have a poke at it because I was only just messing around with it in the repl.
David Chambers
@davidchambers
Okay. chainRec is new to me so I don't have a good grasp on it yet.
Scott Christopher
@scott-christopher
It's perhaps most useful for repeatedly running IO or Future actions repeatedly without having to worry about stack space.
For example, you can define functions like forever which will repeatedly run the same action sequentially for any given ChainRec.
const forever = m =>
  chainRec((next, _, _) => m.map(_ => next(void 0)), void 0);
David Chambers
@davidchambers
Intriguing!
Scott Christopher
@scott-christopher
and I have my suspicions that the ChainRec instance for Array can be used to implement a relatively efficient parser ... but that's an idea to explore another day :D
David Chambers
@davidchambers
:)
Irakli Safareli
@safareli
@scott-christopher good catch!
David Chambers
@davidchambers
Welcome to the sanctuary-js team, @safareli. :tada:
Irakli Safareli
@safareli
Thanks for having me 🍓
David Chambers
@davidchambers
Excellent emoji choice.
David Chambers
@davidchambers
I just created a sanctuary tag on Stack Overflow. You may like to subscribe to it. Also, I posted a question: Custom equality semantics for Immutable.js data structures. I'd love to be able to use maps and sets when working with Sanctuary, but for various reasons neither the native types nor the Immutable.js equivalents are currently suitable.
Keith Alexander
@kwijibo
:point_up: September 17, 2016 1:41 PM @scott-christopher are there (more specific) common use cases you could name, to explain it a bit more?
Irakli Safareli
@safareli
other use case is with Free monad, you can do monadic recursion when you are working with Free and as long as your target monad to which you are folding to is ChainRec it will not blow stack
here is test case from Free
Keith Alexander
@kwijibo
Nice
Irakli Safareli
@safareli
for a bit context the Free was not stack safe and for it to be stack safe target monds should have some common interface so that it could depend on it. now we have ChainRec, in purescript it's MonadRec, and Free and other structures could use it for doing safe monadic recursion. if you are interested in that here is a paper about that https://github.com/functorial/stack-safety-for-free/blob/gh-pages/index.markdown
Irakli Safareli
@safareli
Also resently I saw rpominov/static-land#26, I don't quite understand what this runGenerator actually does but using ChainRec it's now stacksafe :D
Keith Alexander
@kwijibo
@safareli interesing thanks
Pavel Meledin
@btbvoy
Hi everyone. Could anybody share a link to open source project which widely uses sanctuary ? I'm interested to see how exactly communication with outside world (like DB, external services) is implemented also interested in the way how error handling is done. Would be awesome if such a project is already used in real production with nodejs for instance. Thanks in advance
David Chambers
@davidchambers
The generate script which builds the Sanctuary website is one example of handling errors with the Either type, @btbvoy. For DB interactions one could use a library such as Fluture. The only large project I'm aware of that makes heavy use of Sanctuary is not open source, but reading this blog post will give you an idea of how I used Ramda and Sanctuary in that project.
Brad Compton (he/him)
@Bradcomp
Is Sanctuary moving towards the prefaced method names per the new FL spec?
David Chambers
@davidchambers
Yes it is, @Bradcomp. I was working on updating #216 last night. I got stuck on the laws after changing sequence to traverse. I think I'll .skip those tests and ask @scott-christopher for assistance. One question is whether Maybe#fantasy-land/map should replace Maybe#map or whether we should have both. What's your opinion on this, Brad?
Pavel Meledin
@btbvoy
@davidchambers thanks David :-)
Irakli Safareli
@safareli
I think as a public API we should also have normal non namespaced functions. so if you have Santuary/Maybe object you could call map on it. But depend on FP interface when Santuary functions are taking some Structure as an argument