These are chat archives for ramda/ramda

18th
Feb 2017
Keith Alexander
@kwijibo
Feb 18 2017 00:08
Yep
Scott Santucci
@ScottFreeCode
Feb 18 2017 02:24
Fun fact: I have been learning a library in another language that may be helpful for one of my non-web projects, and it uses callbacks for behavior fairly extensively... and every time I see data passed to the function before the callback, now I think, "But if you curried it and took the data last the behavior of this function with a given callback would become reusable!"
Thanks. Thanks a lot. :laughing:
(In all seriousness, I might look at whether I can implement a generic "flip and partially apply" function in the other language in question, so I can stop being annoyed by the missed opportunities.)
Drew
@dtipson
Feb 18 2017 02:49
@xgrommx that's super cool, though a bit dizzying to work through how it works
Keith Alexander
@kwijibo
Feb 18 2017 05:36
@MReinigJr to understand the map here, :point_up: February 17, 2017 11:42 PM
it might help if I add
Task.of = x => Task((_, res)=>{ res(x) })
Keith Alexander
@kwijibo
Feb 18 2017 06:04
Keith Alexander
@kwijibo
Feb 18 2017 07:31
Or you could decouple the forEaching
Future.prototype.chainForEach = function(f){
    return new Future((rej, res)=>{
        this.fork(rej, xs => xs.forEach(x => f(x).fork(rej, res)))
    })
}

listEmails()
.chainForEach(getEmail)
.map(email => blah(email))
.fork(err, succ) //=> handlers get called for each email
Keith Alexander
@kwijibo
Feb 18 2017 10:54
That's really nice @xgrommx
Can you explain to me what monadPlus is?
Denis Stoyanov
@xgrommx
Feb 18 2017 12:36
monadplus is just a like monoid with restriction
with monad restriction
mzero /mplus in haskell
David Chambers
@davidchambers
Feb 18 2017 13:46
@ram-bot help
Gabe Johnson
@gabejohnson
Feb 18 2017 14:05
@davidchambers feature testing?
David Chambers
@davidchambers
Feb 18 2017 14:05
Haha, yep!
Rick Medina
@rickmed
Feb 18 2017 15:04
@kwijibo chainForEach was derived from the need of avoid the rejection of one task in a list preventing the resolution of the other ones?
Brad Compton (he/him)
@Bradcomp
Feb 18 2017 16:00
@ram-bot
var a = function(x) { return a(x + 1); }; a(0);
ram-bot
@ram-bot
Feb 18 2017 16:00
Maximum call stack size exceeded
Michael Reinig
@MReinigJr
Feb 18 2017 17:07

@kwijibo

also, https://github.com/fluture-js/Fluture#parallel might be of interest

This is really cool and is exactly what I was trying to accomplish. Also, wrapping the results into Either like they show in the example is a great idea. Thanks!

Michael Reinig
@MReinigJr
Feb 18 2017 17:37
@kwijibo I just tested your Future.chainForEach and it works great!!! I refactored my getEmails to be getEmail, which now returns a single future. This is WAY more clear than what I had before!
Keith Alexander
@kwijibo
Feb 18 2017 17:38
@rickmed I believe that is @MReinigJr's motivation
@MReinigJr great :)
I guess the out-of-the-box way to achieve it is
listEmails()
.fork(
  console.error,
  R.forEach(emailID =>
        getEmail(emailID)
        .map(processEmail)
        .fork(console.error, console.log)
   )
)
Michael Reinig
@MReinigJr
Feb 18 2017 17:42
Could someone please explain what the fantasy land chainRec does? I see that Ramda Fantasy supports if for Futures. So an explanation as it relates to Futures would be much appreciated. Thanks in advance!
@kwijibo You are right in your response to @rickmed. This is exactly what I was trying to achieve.
Rick Medina
@rickmed
Feb 18 2017 17:45
@MReinigJr what I do is to recover within the traverse (to avoid the overall failing) to not tie myself to a specific implementation
Keith Alexander
@kwijibo
Feb 18 2017 17:46
@rickmed cool - can you share a short example?
Rick Medina
@rickmed
Feb 18 2017 17:46
@MReinigJr ramda/ramda#2086 for a use case for chainrec
Michael Reinig
@MReinigJr
Feb 18 2017 17:47
@kwijibo Thanks for the out-of-the box solution. It really helps to gain perspective on what is really kind of happening with your chainForEach or more confusing, what the R.chain in getEmails is doing. :)
Rick Medina
@rickmed
Feb 18 2017 17:52
something like this
const catDir = dir =>
  R.pipeK(
    ls,
    R.traverse(Task.of, R.pipe(
      cat,
      t => t.fold(id, id))),  // recover rejected EISDIR tasks
    withoutDirs
  )(dir)
withoutDirs filters the items in the list which are error objects (which would previously reject the whole task). In t => t.fold... you can wrap in either or whatever, I just did it generically
Rick Medina
@rickmed
Feb 18 2017 17:58
caveat: this is using ramda's traverse which is outdated about the ap args order from current FL, so it works with data.task v1.x, not sure about the other implementations
Keith Alexander
@kwijibo
Feb 18 2017 18:00
nice, thanks @rickmed
Rick Medina
@rickmed
Feb 18 2017 18:01
oh, also, the caveat about it not being lawful bc data.task monad ap is parallel
Keith Alexander
@kwijibo
Feb 18 2017 18:01
one option would be to recover with a Nothing (and wrap in a Just if it's a success)
and then use https://sanctuary.js.org/#justs to get rid of the failures
@ram-bot S.justs([S.Just('foo'), S.Nothing, S.Just('baz')])
ram-bot
@ram-bot
Feb 18 2017 18:03
S.justs is not a function
Keith Alexander
@kwijibo
Feb 18 2017 18:03
damn :)
Rick Medina
@rickmed
Feb 18 2017 18:03
or have specific error types and then pattern match in final fork a la DDD :)
Keith Alexander
@kwijibo
Feb 18 2017 18:03
(it should have returned ["foo", "baz"])
Yeah, I was wondering what the best practice with DDD is - do you make custom types with Maybe/Either style behaviour? or do you wrap the custom types in Maybe/Either - treating them as flow control structures?
I kinda thought the latter, but I don't know as much about DDD as I'd like
Rick Medina
@rickmed
Feb 18 2017 18:10
I would make custom types for left (returning a custom type for all possible failures, or at least the ones you are interested in) and right (modeled after your domain). I've not done it in js bc, you know, types -not sure if worth it using something like union-type)
Keith Alexander
@kwijibo
Feb 18 2017 18:38
I have a vague idea that part of the folktale rewrite will make it easier to create custom types
Mick Dekkers
@mickdekkers
Feb 18 2017 19:13
Can I reduce over an object? I want to do something with the keys and values and return an array (of variable length)
λ • Geovani de Souza
@geovanisouza92
Feb 18 2017 19:15
@ram-bot R.toPairs
@SoullessWaffle ^
Mick Dekkers
@mickdekkers
Feb 18 2017 19:16
@geovanisouza92 great, thanks!