Kenny Fellows Kenny Fellows - 1 month ago 9
Javascript Question

Why isn't this basic "R.useWith" is not working properly?

I'm fairly new to Ramda, and still trying to wrap my head around certain functions. Currently, I'm struggling a bit with

R.useWith
.

Let's say I have an array of objects:

let myArray = [
{
a: 'wat',
b: 'foo'
},
{
a: 'something',
b: 'something_else'
},
{
a: 'booyah',
b: 'duh'
}
];


And I want to set a property of
foo
to equal
bar
on EACH object. I know there are several ways to do this, and I'm only using this as a contrived example while I try to learn this function. One way would to do this:

let setFooToBar = R.assoc('foo')('bar');
let mapMyArray = R.map( R.__, myArray );


So at this point, I have a function
setFooToBar
that expects an object, and will set property
foo
to
bar
, and I have a function
mapMyArray
that expects a function, and will map each
object
from
myArray
to that function. So, as expected, this works:

mapMyArray( setFooToBar )


Now, what I don't understand, is why THIS approach isn't working the way I'd expect it to:

let callFirstWithSecond = ( arg1, arg2 ) => arg1( arg2 );

R.useWith(
callFirstWithSecond,
[
R.map( R.__ ),
R.assoc('foo')
]
)( myArray, 'bar' )


I would expect this to return the same thing as the previous approach, a new array of objects, each with a new property of
foo
set to
bar
. However, it is actually returning a new function. I can't figure out where I'm missing arguments.

Thanks in advance for any help!

Answer

There is nothing wrong with your understanding of useWith.

The problem is the use of the placeholder, R.__ in

 R.map( R.__ )

Using the placeholder as the last argument does not make sense. It is used as a signal that "the argument that goes here will be supplied later." Since Ramda functions are already curried, using it without anything to follow is a no-op.

let someFunc = (p1, p2, p3, p4) => 'whatever';
someFunc(argA, __, __, argD) ~>
    (p2, p3) => someFunc(argA, p2, p3, argD)

// but
someFunc(argA, argB, __, __) ~>
    (p3, p4) => someFunc(argA, argB, p3, p4) ~==
    someFunc(argA, argB) 

You can get the behavior you want by replacing R.map( R.__ ) with R.flip( R.map ).

You can see this in action in the Ramda REPL.

Comments