Was trying to work out a pickByIndex (the one in the cookbook doesn't really work for my purposes) and ran into something I can't quite figure out.

This works perfectly well:

This works perfectly well:

`compose(ap, map(nth))([0,2,2,3,4,1])([['a','b','c','d','e','f','g']])`

But I'd prefer the signature not require the extra call to

`of`

for the sample source. So I tried this:```
const pickByIndex = useWith(
compose(ap, map(nth)),
[identity, of]
);
```

But that returns a function instead of a result. I think something in the realm of arity is getting mucked up, but I can't for the life of me figure out what

Usage would just be this:

```
const specificPick = pickByIndex([0,2,2,3,4,1]);
...
specificPick(['a','b','c','d','e','f','g'])
```

all part of a coding exercise for a check-digit verification where I'm slowly trying to eliminate all reference to intermediate arguments and show off what Ramda can do with a complex set of requirements: http://goo.gl/HThlrw

is there a mistake in the type sig for addIndex on the doc site?

((a … → b) … → [a] → *) → (a …, Int, [a] → b) … → [a] → *)

the parens seem screwy

Yes, the third opening paren should be two opening parens.

it's one of the most convoluted signatures we have.

anyone use golang/clojure?

@CrossEye @Bradcomp Can you give me exercises so i get familiar with ramda.js?

What is the proper type there?

@joneshf you too :package:

Something like this seems reasonable as an actual signature that would type check:

`addIndex :: ((a -> b) -> [a] -> c) -> (Number -> a -> b) -> [a] -> c`

But that's not what it's actually doing.

@6ewis I think this is pretty good if you do the exercises in ramda: http://reactivex.io/learnrx/

@6ewis one way you can do that is to copy paste https://cdnjs.cloudflare.com/ajax/libs/ramda/0.20.1/ramda.min.js into the console

It'll put

`R`

on the window, so you can access it within the exercises.
For instance, the first exercise says to use

`forEach`

on the array prototype. Instead you could use `R.forEach`

@joneshf it seems to easy but not a bad idea

@joneshf: the trouble is that

`addIndex`

works not only for binary functions, but also ternary or general n-ary ones. Moreover it works with polyadic callback functions too. Thus it works both with `map:: (a -> b) -> [a] -> [b]`

but also with `reduce:: (b -> a -> b) -> b -> [a] -> b`

.
@CrossEye right, so it wouldn't work with `reduce`

as is, but if you flip some args it would. If we had:

`reduce :: (a -> b -> b) -> [a] -> b -> b`

It would type check, since we could add parentheses to get something like:

`reduce :: (a -> (b -> b)) -> [a] -> (b -> b)`

Then we have:

`a`

in`addIndex`

unifies with the`a`

in`reduce`

`b`

in`addIndex`

unifies with the`b -> b`

in`reduce`

`c`

in`addIndex`

unifies with the`b -> b`

in`reduce`

But it seems wrong to have to do that as well.

well, not really wrong

cumbersome

@CrossEye, I'm somewhat familiar w/ ramda's type sigs as I've spent a little time w/ purescript and haskell (though not a lot, still learning); however, I'm not sure how to "read aloud" the ... in the sigs

i appreciate your pointing out where the paren is missing in the sig for addIndex, but the various "..." are still confusing me a bit, as far as how to read them, though I do understand what addIndex does

::addIndex

@6ewis The Mostly Adequate Guide has exercises (starting in chapter 4), and they actually use Ramda as the library.

@Bradcomp thanks funny enough i read it up to chapter 3

@6ewis Have you seen the Advent of Code problems? It's not Christmas but they're still fun, and code puzzles are a great opportunity for learning a new paradigm / library / language

Almight Ramda gurus, masters of the functional paradigm, why does compose with transduction seem to reverse the order of compose? Example,

```
let transducer = R.compose(R.filter(R.gte(R.__, 15)), R.map(R.add(13)))
R.transduce(transducer, R.flip(R.append), [], R.range(0, 20))
// output: [28, 29, 30, 31, 32]
```

It looks like the application of functions is from left to right even though compose is supposed to go from right to the left, right?

@Bradcomp are they problems that require a functional approach to be solved?

@LeonineKing1199 compose goes from right to left, but a transducer stack processes left to right?

sorry, didn't meant to put '?' on the end, I was making a statement

@LeonineKing1199 to understand that, look at how compose works together with the function that's returned by a transducer, e.g. R.map (when called w/ one arg)

you're basically composing configuration rather than values: compose is still working right to left: but what it's passing right to left are partial functions that are used at the end of each operation they're getting passed into

I wrote up a longer explanation at the end of this transducer article: https://medium.com/@dtipson/everything-reduced-transducers-in-javascript-8ea3459bc7f9

I'm looking at ramda's source code now, and it's a little bit hard to follow what's going on; I suggest looking at the definition of clojure's

`comp`

function and the single-arg impl for clojure's `map`

function
it's easier to see therein how the right-to-left composition result gets turned inside out

to result in the transformer stack being applied left-to-right

Lol I actually realized exactly what Ramda was doing. I remembered this article: http://phuu.net/2014/08/31/csp-and-transducers.html

and then I realized that Ramda is composing from right to left, it's just not how I would think of it. In my example, the map is the overarching function while the filterererererer is the nested. So it's like a reverse sort of hierarchy

check out these stripped down gists: composing functions that consume functions for a tail operation and then return configured functions: https://gist.github.com/dtipson/a06f1c549721f4e79dfc#file-composition-higher-order-js vs composing functions that just consume and return values https://gist.github.com/dtipson/8577067066732795575d#file-compose-just-values-js

Using this as an example of what Ramda might conceptually implement,

```
function mapping(transform) {
return function (reduce) {
return function (result, input) {
return reduce(result, transform(input));
};
};
}
function filtering(predicate) {
return function (reduce) {
return function (result, input) {
return (
predicate(input) ?
reduce(result, input) :
result
);
};
};
}
```

Looking at this, I now see how the composition works.

correct, the left-most argument of compose ends up corresponding to the the outer-most function in the transformer stack, so that its effects happen first

@michaelsbradleyjr Yes! Exactly! I realized that literally like 2 minutes after I posted here lol :P

God, transducers are cool. I, like, *need* to know how all of this works on a lower-level...

there are some standalone libraries which might lay it out more directly: https://github.com/jlongster/transducers.js

that article of mine that I linked also walks through building them directly (in a slightly less powerful form, since there's no transducer protocol, so I have to resort to special Symbol keys and a custom reduce to implement things like take)

Yeah, I bookmarked the link. I'll check it out when I have time :)

@Bradcomp are they problems that require a functional approach to be solved?

@6ewis I wouldn't say they require a functional approach, but many of them have good functional solutions.

If you want some specific problems for learning FP, there's 99 Haskell Problems

@Bradcomp thank you exactly the kind of stuff I was looking for

:+1:

@michaelsbradleyjr: still incomplete, but a start at explaining our type sigs: https://github.com/ramda/ramda/wiki/Type-Signatures. The ellipsis represent repetition. "There are some number more similar elements here. "

@CrossEye thanks, so can you help me "read" the sig for the first arg of addIndex?

((a … → b) … → [a] → *)

so, altogether, that argument could be something like R.map

i read the first ... as saying that the function we'd expect as the first arg to, say, R.map, could be variadic in its arguments; e.g.

`a`

or `a, a`

, or `a,a,a,...`

but the second

`...`

, what does it represent? can you give an example?
clojure's

`map`

, for example, allows multiple collection as the 2nd...nth args
but I don't see how to interp. the second

`...`

in that manner
but maybe that arg's type sig should be

`((a … → b) → [a] ... → *)`

good evening

oh boy i haven't been here for way way too long

hi, @gilligan!

real life took over.. time to have add more ramda to my life again ;)

@michaelsbradleyjr: T

seems like there was another gitter client update. Seems like it improved a bit

Hee's a simplification that doesn'hat could take for instance,

`map:: ((a -> b) -> [a] -> [b])`

and convert it to `addIndex(map):: (a-> Number -> [a] -
t

god, I hate the mobile client that won't let me edit!

so yes @gilligan, some improvements, but not nearly enough.

Let me try again.

I'm going to talk about a simplified

`addIndex`

that adds only the index and not also the collection to the callback.
@CrossEye compared to slack it is still pretty bad- yes

It converts

`map:: ((a -> b) -> [a] -> [b]`

to `addIndex(map):: (a -> Number -> b) -> [a] -> [b]`

.
@CrossEye i got that, makes sense; the 2nd ellipsis in the first arg doesn't make sense to me

But this same function converts

`reduce:: ((b-> a -> b) -> b -> [a] -> [b]`

to `addIndex(reduce):: ((b-> a -> Number -> b) -> b -> [a] -> [b]`

.
Note that the number of arguments to the callback varies.

The first one has one argument, the second one has two. This is agnostic to that arity. It adds

`Number`

as an additional parameter.
(In the real function, it also adds the entire list as a parameter to the callback.)

yes, that makes sense too, I still don't get the second ellipsis here:

`(a … → b) …`

Sorry, the second ellipsis has to do not with the callback but with the function as a whole.

`map`

is binary. `reduce`

is ternary. We can imagine even larger arguments lists.
(didn

(didn't see your response until I'd finished typing all the

`reduce`

stuff. I can be blind.)
np, and I can move on w/ a general sense of how to use it; I don't readily parse those two ellipsis into the binary,ternary,4+ meaning

I realize that ramda faces some challenges here, given the dynamism w.r.t. types and arity

So in

`map`

the second `...`

represents an empty list of arguments. In `reduce`

it represents `b`

the argument(s) between the callback and the list of

`[a]`

's.
and in

`addIndex(:: (a -> b) -> c -> d -> e -> [a])`

it would represent `c, d, e`

.
sorry, that wasn't complete, but the notation is invented anyway.

so why isn't it

`((a … → b) → … → [a] → *)`

vs. `((a … → b) … → [a] → *)`

or the

`→`

is implied if a type variable is followed by `...`

?
Just a real inconsistency in how various people create these. I think it should have the arrow.

But even throughout this conversation, I didn'

didn'

t notice it missing until now.

so, to be consistent, we could have:

`((a → … → b) → … → [a] → *)`

Yes, that would be better. And a PR for that would be welcome.

ok

It's a shame that this is one of the earliest functions alphabetically. :smile:

thanks for persevering. I was clearly missing the point.

now, I could see in some cases, where one might not expect a function to be curried, to use tuple notation

which I've seen in purescript

something like:

`( ( ( (a, …) → b ), …) → [a] → *)`

the parens start to get a little heavy, though; but one could, say, use {} to denote tuples

yes, we're also inconsistent about this. We probably could use tuples in callbacks where we never take advantage of the currying.

`({({a, …} → b ), …} → [a] → *)`

just thinking aloud on that one, not sure it's really better

See #1554 for discussions about this... not yet resolved. But your contributions would be most welcome.

anyway, thanks for entertaining my inquiries! :-)

my pleasure.

Does this seem useful to anyone http://goo.gl/QJ03To ?

I'm absolutely certain that on a few occasions I've needed exactly that, but I don'

t recall any details now.

huh.. you have some really weird, unusual indentation going in there @asaf-romano hehe

anyway - never found myself doing/needing that actually

I like it. It's actually read-able.

it's an operator in mongo's aggregation system, and at least there it's remarkably useful

I'm not sure whether it should act on a single object (as the repl script does) or on a collection ("auto"-chain)