These are chat archives for ramda/ramda

25th
Feb 2016
John Games
@johnnygames
Feb 25 2016 01:04
heyoo i see a command in the docs for a partial build of ramda
can someone help me with that? im not sure where to run it? in node_modules/ramda?
Scott Sauyet
@CrossEye
Feb 25 2016 01:10
No, just from the root.
David Chambers
@davidchambers
Feb 25 2016 01:34
@johnnygames, you'll need to clone the repository. We don't include the build script in the distribution.
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 07:56
if I have {a: 'b', c: 'd'}, what's a nice way to get [{a:'b'},{c:'d']] ?
Raine Virta
@raine
Feb 25 2016 08:03
@ram-bot pipe(toPairs, map(apply(objOf)))({a: 'b', c: 'd'})
ram-bot
@ram-bot
Feb 25 2016 08:03
[ { a: 'b' }, { c: 'd' } ]
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 08:04
thanks @raine
Raine Virta
@raine
Feb 25 2016 08:07
np
Risto Stevcev
@Risto-Stevcev
Feb 25 2016 11:32
I was wondering how I would make the following scenario ramba-esque,
I have a generator function that uses co and it does a bunch of checks, something like this:
if (condition1)
  return 'Error msg 1'
if (condition2)
  return 'Error msg 2'
...
let resource = new Resource(body)
try {
  yield resource.save()
}
catch (err) {
  return err.message
}
return 'Successfully saved'
It uses co.wrap to return a promise that my route then handles. I want it so that the conditions are handles using Either type, and then maybe I could just use a Promise without yielding for the saving part
There are some limitations in library I'm using to have it validated some conditions before save, though I might get around that eventually
Risto Stevcev
@Risto-Stevcev
Feb 25 2016 13:20
I came up with something, but I wonder if there's a better way. I had to create a function that will resolve a Promise into an Either type so that it can be used with pipeP and composeP:
// Some conditions to check before save
let sqrt = n =>
    n < 0 ? S.Left('Cannot represent square root of negative number')
          : S.Right(Math.sqrt(n))
let square = n => n <= 2 ? S.Left('Must be > 4') : S.Right(n * n)
let check = body => S.Right(body).chain(sqrt).chain(square)

// Wraps a promise into an either type
let eitherOnFulfilled = (value) => Promise.resolve(S.Right(value))
let eitherOnRejected = (reason) => Promise.resolve(S.Left(reason))
let liftEitherP = (promise) => promise.then(eitherOnFulfilled, eitherOnRejected)

// Simulate save failure and success
let saveFail = _ => Promise.reject('Save failed')
let saveSuccess = _ => Promise.resolve('Save successful')

let save = body => body.isLeft ? liftEitherP(Promise.reject(body.value))
                               : liftEitherP(saveSuccess()) 
                             //: liftEitherP(saveFail())

R.pipe(check, save)(9).then(result => console.log(result.isLeft ? 'Error: ' + result.value : result.value))
// returns 'Save successful'

//R.pipe(check, save)(0).then(result => console.log(result.isLeft ? 'Error: ' + result.value : result.value))
// returns 'Error: Must be > 4'

//R.pipe(check, save)(-1).then(result => console.log(result.isLeft ? 'Error: ' + result.value : result.value))
// returns 'Error: Cannot represent square root of negative number'

//checkAndSave(9).then(foo => console.log(foo))
//R.pipeP(_ => Promise.resolve(3), eitherP)(44).then(foo => console.log(foo))
I pretty new to ramda, so I'm wondering if this is correct
Risto Stevcev
@Risto-Stevcev
Feb 25 2016 14:20
Ignore the last two comments
Scott Sauyet
@CrossEye
Feb 25 2016 14:35
Well, since I haven't had ant time to look at them, I'm glad to ignore them. :smile: did you figure something out?
*any time
Risto Stevcev
@Risto-Stevcev
Feb 25 2016 14:40
@CrossEye Well the general gist I'm getting is that it would be nice to have something like pipeEitherP and liftEitherP, since a promise has an onReject clause. This would let you pipe a series of checks and asyncs, which would fail on the first Left result and wouldn't execute the rest of the pipeline.
At which point you could just either process the Right result or handle the Left error
Unless there's a better way of creating that functionality that I'm not seeing
Scott Sauyet
@CrossEye
Feb 25 2016 14:46
Hmmm. We've kept the Algebraic types such as Either out of the core so far. But I can see the appeal.
Keith Alexander
@kwijibo
Feb 25 2016 15:04
you could have a two step function like pipeP(f,g,h)(catchError)
or (less intuitively) pipeP(catchErr, f,g,h)
pipeP is pretty clunky without a way to do the .catch
Michael Hurley
@buzzdecafe
Feb 25 2016 15:08

We've kept the Algebraic types such as Either out of the core so far.

@davidchambers is pitching a Set type; an I intend to pitch a maybe function that returns a Maybe, so you can make any function null-safe by const ensafen = (f) => compose(maybe, f)

GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:27
is there a shortcut for r.complement(r.isEmpty) ?
because i wrote it so many times, but if I define it myself, i will have to document it : )
LeonineKing1199
@LeonineKing1199
Feb 25 2016 19:30
You could always just append your own custom functions to the ramda module directly
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:30
yes, but i will have to document it then
LeonineKing1199
@LeonineKing1199
Feb 25 2016 19:30
Because Node caches required modules, you simply mutate the exports of the Ramda module once and everywhere else in your app wil lsee it
so?
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:30
although an r.isNotEmpty is not hard
LeonineKing1199
@LeonineKing1199
Feb 25 2016 19:30
documentation is a good thing in code
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:30
but one such function and the gates are open for any number of such functions
LeonineKing1199
@LeonineKing1199
Feb 25 2016 19:31
... and?
That sounds like a positive to me.
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:32
why would it be a positive?
LeonineKing1199
@LeonineKing1199
Feb 25 2016 19:33

Because you have a globally-scoped and uniform interface to functions that you find useful.

On the other side, why would it be a negative?

GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 19:33
functions have a domain, i now need this function, but who knows if i will need it tomorrow. i can't define a domain that will also mean that i will have to maintain something somewhere else than here
ideally these things are in a lib, adding something to ramda i would basically fork it
don't get me wrong, what you are saying is certainly what it seems normal, i just have itches that are not normal : )
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 22:07
how do i read a property from an object if I don't know the property name, but I know there is only one of them. I can do r.values(obj)[0] but it's ugly : )
Scott Sauyet
@CrossEye
Feb 25 2016 22:17
still ugly, but perhaps slightly better (for a somewhat peculiar requirement): compose(head, values)
GÁBOR Áron Zsolt
@ashnur
Feb 25 2016 22:35
: D