These are chat archives for ramda/ramda

2nd
Feb 2016
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 07:13
imagine i have const x = {a: 'B', c: {...}} (not my idea) and then i have to do something like if x.a.toLowerCase() equals 'b' then call a function(a.c)
i know about propEq and propSatisfies, but somehow couldn't figure out a nice way to do it which is short but readable
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 07:23
in fact, the function over c would be a very similar one, check and read deeper
i am writing stuff like if ( r.toLower(r.propOr('', 'a', {a: 'b'})) == 'b' ) ...
Scott Christopher
@scott-christopher
Feb 02 2016 07:45
@ashnur: perhaps something like the following?
(x, fn) =>
  R.when(R.propSatisfies(R.compose(R.equals(x), R.toLower), R.prop('b')),
         R.compose(fn, R.prop('c')));
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:50
@scott-christopher that dies in a very ugly way if for some reason x.b is not a string. which is a possibility given that i am recursively mapping over a JSON that I got from the server :)
I ended up doing
const pathCond = r.curryN(3, (fn, path, obj) => !fn(obj) ? undefined : r.path(path, obj))
Raine Virta
@raine
Feb 02 2016 08:52
ashnur: doesn't R.curry work there?
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:53

and the fn is

const isValid = (obj) => r.toLower(r.propOr('', 'status', obj)) == 'valid'

obviously I could parametrize this if I ever need something similar. and yeah, it's ugly. but I really don't want a can't call toLowerCase on undefined exception :)

@raine probably, i don't know, I always use curryN because with curry i am in the dark what's happening
had some issues where i got back a function no matter what
Keith Alexander
@kwijibo
Feb 02 2016 08:55
i think you only need curryN with variadic functions?
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:55
i don't think it makes a big difference, if I use curryN instead of curry, does it? :)
Keith Alexander
@kwijibo
Feb 02 2016 08:55
if your function always has a fixed number of non-optional arguments, R.curry can use the the function's length
Aldwin Vlasblom
@Avaq
Feb 02 2016 08:55
@ashnur R.curry looks at fn.length to know the arity. :)
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:56
seriously, is this curry thing this important?
Scott Christopher
@scott-christopher
Feb 02 2016 08:56
It's not important. People are just trying to help you.
Aldwin Vlasblom
@Avaq
Feb 02 2016 08:56
We just don't want you to be in the dark. :(
Keith Alexander
@kwijibo
Feb 02 2016 08:57
it's just a bit nicer if you don't have to write the arity all the time
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:57
oh, thanks
i don't have to, but i like to write it
Keith Alexander
@kwijibo
Feb 02 2016 08:57
fill your boots then :)
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:57
i would much rather have a nice solution for the default '' string because that's way more problematic
i could perhaps check for the method if it exists
Aldwin Vlasblom
@Avaq
Feb 02 2016 08:59
Have you looked into using something like Maybe? The sanctuary package provides some neat solutions to get possibly undefined attributes and performing transformations on the result only if it exists.
Keith Alexander
@kwijibo
Feb 02 2016 08:59
+1
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 08:59
i was thinking about Maybe, but I am scared of monads
they tend to spread virally
Keith Alexander
@kwijibo
Feb 02 2016 09:01
you can do something a little lighter-weight like const maybe = f => x => typeof x!='undefined'? f(x) : x
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 09:01
@kwijibo thing is, it should be typeof x === 'string'
honestly, i blame the backend i have to talk to. really annoying API response
Keith Alexander
@kwijibo
Feb 02 2016 09:03
const whenString = R.when(R.is(String))
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 09:03
oh
Keith Alexander
@kwijibo
Feb 02 2016 09:03
whenString(R.toLower)(x)
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 09:03
i haven't used .when yet for anything, but looks nice
thanks @kwijibo
Keith Alexander
@kwijibo
Feb 02 2016 09:04
np
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 09:04
now, next thing, how to store a JSON into datascript :D
Keith Alexander
@kwijibo
Feb 02 2016 09:05
what's datascript?
has a js api
Scott Christopher
@scott-christopher
Feb 02 2016 09:09
@ashnur If you need a default value when the key doesn't exist then you'll need to look into ifElse rather than when.
const thing = R.curry((x, fn, def, obj) =>
  R.ifElse(R.both(R.has('status'), R.propSatisfies(R.compose(R.equals(x), R.toLower), 'status')),
           R.compose(fn, R.prop('c')),
           R.always(def))(obj));

thing('success', R.inc, 42, { 'status': 'success', c: 5 });
// 6
thing('success', R.inc, 42, { c: 5 });
// 42
You can then add/remove args from that function as necessary.
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 09:09
@scott-christopher will check soon, thanks to you too
Scott Christopher
@scott-christopher
Feb 02 2016 09:10
:thumbsup:
Keith Alexander
@kwijibo
Feb 02 2016 09:10
As an aside, I've been thinking that if instead of one-at-a-time currying, you did it in steps, where some of the steps are variadic, you could have a library that made point-free compositions a little more concise
eg, if the first argument to, X.map is a unary-function (where X is my hypothetical library)
then X.map could take multiple arguments in that first step, and pipeline them
X.map(f,g)(list) instead of R.map(R.pipe(f,g))(list)
Keith Alexander
@kwijibo
Feb 02 2016 09:16
or X.propSatisfies( R.toLower, R.equals(x))('status') instead of R.propSatisfies(R.compose(R.equals(x), R.toLower), 'status')
(seems pretty common to need to create a pipeline/composition to pass to a HOF in a parent pipeline, and the nesting can make it tricky to read/write)
Keith Alexander
@kwijibo
Feb 02 2016 09:24
X.pipeP(f,g)(handleError)(x) instead of R.pipe(R.pipeP(f,g), p=>p.catch(handleError))(x)
(am I missing something, or do you need to nest a pipeP inside a pipe if you want to catch the error? ... I'm not liking promises very much lately )
James Forbes
@JAForbes
Feb 02 2016 10:03
R.propOr is pretty great in this situation if you want a default value
particularly primitives like strings
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 10:27
ok, silly question time because i wasted 5 minutes thinking about this. how do you get from {0: 'foo', 2: 'bar'} this: ['foo',,'bar']?
Aldwin Vlasblom
@Avaq
Feb 02 2016 10:49
Array.apply(null, {0: 'foo', 2: 'bar', length: 3}) works, but you'd need to figure out and assoc the length beforehand. And it's hacky. Why do you want this rather than just values?
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 11:16
need the keys
forgot about the Array.apply hack :)
Robert K. Bell
@r-k-b
Feb 02 2016 11:18
R.toPairs({0: 'foo', 2: 'bar'}) ?
Aldwin Vlasblom
@Avaq
Feb 02 2016 11:28
^ That. If all you're doing it for is maintaining the keys.
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 11:54
i asked the backend to send me damned arrays when it's integer keys
i mean, it's a List for them
boxofrox
@boxofrox
Feb 02 2016 12:48
sounds like a fun API. I'm curious why the arrays are sparse. makes sense they'd send objects instead of sparse arrays to avoid transmitting all the absent elements as commas. e.g. {0: 'foo', 10: 'bar'} instead of ['foo',,,,,,,,,,'bar'].
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 12:52
@boxofrox they shouldn't be, and the key shouldn't matter, but I've burnt myself in the past by trusting others and losing information because "we are not going to need it"
Hardy Jones
@joneshf
Feb 02 2016 13:53
WAGNI?
Raine Virta
@raine
Feb 02 2016 13:54
wagni? yagni?
GÁBOR Áron Zsolt
@ashnur
Feb 02 2016 14:08
??
Keith Alexander
@kwijibo
Feb 02 2016 16:36
This message was deleted