@ram-bot

```
const filterM = (of, p) => reduceRight((x, acc) => liftN(2, (flg, v) => flg ? [x, ...v] : v)(p(x), acc), of([]));
const subsequences = compose(reverse, filterM(of, always([true, false])))
const insertEverywhere = x => xs => {
if(xs.length) {
const [y, ...ys] = xs
return [[x, ...xs], ...map(v => [y, ...v], insertEverywhere(x)(ys))]
} else return [[x]]
}
const permutations = reduceRight((x, xs) => chain(v => insertEverywhere(x)(v))(xs), [[]])
const choices = composeK(permutations, subsequences)
choices([1,2,3])
```

```
[ [],
[ 3 ],
[ 2 ],
[ 2, 3 ],
[ 3, 2 ],
[ 1 ],
[ 1, 3 ],
[ 3, 1 ],
[ 1, 2 ],
[ 2, 1 ],
[ 1, 2, 3 ],
[ 2, 1, 3 ],
[ 2, 3, 1 ],
[ 1, 3, 2 ],
[ 3, 1, 2 ],
[ 3, 2, 1 ] ]
```

nice

@xgrommx you broke my

`R.head`

with that one. I can follow `insertEverywhere`

, that's very cool. I understand what `subsequences`

is doing but haven't yet wrapped my head around how. I get a bit lost with how `filterM`

works, I might need to work filterM out on paper one day. I like trying to solve these though. I really just got my head wrapped around stuff like `liftN(3, (a,b,c) => `${ a } ${ b } ${ c }`)(['hi', 'hello'], ['there', 'ole'], ['buddy', 'pal'])`

@mrosata we had talk about

`filterM`

, `traverse`

and etc earlier
:point_up: April 13, 2017 9:44 PM @mrosata

How to realize currying by a condition?

For example, I want to create a function, which returns curried itself until sum of passed arguments equal 10.

Example:

```
// curryMaker(condition);
// “getResult" should return curried itself until sum of passed arguments equals 10.
const getResult = curryMaker((arg) => arg < 10);
getResult(5)(3)(2); // => 10
```

Can ramda be usefull for this goal?

essentially you want to do recursion if I am not wrong @barbiturat ?

@tusharmath I wanted to avoid a browser’s “scope depth” restriction

Because number of calls can be arbitrarily large

recursive calls increase scope depth in each call

@barbiturat and what should it return if the predicate is false?

```
const { curry, ifElse, always, apply, compose}
const thing = curry((r, p) => function _fn (...args ){
return ifElse(apply(compose(p, r)), always(_fn), apply(r))(args)
})
```

@barbiturat I don't *think* there's anything that does that in Ramda. I can't think of something that would create a function with an unknown arity. I was thinking something like what @galipeopy wrote

```
const curryMaker = (pred, reducer) => (...args) => {
const current = reducer(args)
return pred(current) ? current : next => curryMaker(pred, reducer)(...args, next)
}
const a = curryMaker(R.lt(__, 10), reduce(R.add, 0))
a(29)(-10)(-9)(-1)
```

@xgrommx I will go find that convo and read it. Thank you

however both use recursion @barbiturat , and @mrosata is more accurate since it takes care of remembering the last result

actually I think you can't avoid recursion here @barbiturat, you probably want to review your api and use cases and see if the interface you want is really necessary, or if your willing to compromise between recursion and easy of use

@galileopy might be correct. Even if you wrote a function that wasn't directly recursive, it would still likely be returning a closure of a closure of a closure.

I feel like TCO has been OTW for about as long as I've been writing JavaScript. It must be right around the corner

V8 has it right?

under a flag

possibly. I will look it up

```
$ node --harmony_tailcalls --use_strict
> function go(n) { return go(n + 1); }; go(0)
```

loops forever, no stack overflow :)

yea, that

is nice :)

I just took it for a spin

@galileopy , @mrosata Thank you!

@barbiturat :smile:

@mrosata welcome =)

@xgrommx Was the convo you mentioned from last month w/ @skatcat31 ? I remember that convo, I had https://kai-sassnowski.com/posts/understanding-filterm open in a browser tab for almost a week before closing it w/o reading

right now I'm almost to the bottom though, got my

`filterM`

implementation in Haskell working and most dissected
@mrosata what?)

you said that there was a convo about traverse and filterM from earlier :point_up:, but I didn't find anything. So I assumed you meant the convo from last month

@mrosata what is

`convo`

?
conversation

I think you had just solved for (or was looking for a solution to) "Given a list of integers, produce a list of all possible sums that can be created using the integers from the list" using Ramda and dropped that link to the explanation of that problem and the inner workings of filterM

@mrosata do u need this code?)

not particularly

=)

you could use your

`filterM`

from yesterday right? `R.compose(R.map(R.sum), filterM(R.always([1, 0]))`

something like that right?

@mrosata

`filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]`

predicate should return boolean which should be wrapped in monad

@mrosata

`powerSet = filterM(const [True, False])`

1 and 0 won't work for the predicate?

no

@mrosata only Boolean

That's good to know. I've wanted to try this for some time, flying close to the sun here because I don't know if this will work:

@ram-bot

@ram-bot

```
const filterM = (of, p) => reduceRight((x, acc) => liftN(2, (flg, v) => flg ? [x, ...v] : v)(p(x), acc), of([]));
R.compose(R.map(R.sum), filterM(of, R.always([true, false])))([1, 2, 3, 4, 5])
```

damn you @ram-bot

how do I make @ram-bot evaluate something?

@mrosata

`R.compose(R.map(R.sum), filterM(of, R.always([true, false])))([1, 2, 3, 4, 5])`

u have errors
would it have evaluated otherwise?

@ram-bot

```
const filterM = (of, p) => reduceRight((x, acc) => liftN(2, (flg, v) => flg ? [x, ...v] : v)(p(x), acc), of([]))
R.compose(R.map(R.sum), filterM(of, R.always([true, false])))([1, 2, 3, 4, 5])
```

```
[ 15,
10,
11,
6,
12,
7,
8,
3,
13,
8,
9,
4,
10,
5,
6,
1,
14,
9,
10,
5,
11,
6,
7,
2,
12,
7,
8,
3,
9,
4,
5,
0 ]
```

nice

Also I derive alternative for

`powerSet`

@ram-bot

```
const powerSet = reduceRight((x, a) => ap(concat, map(prepend(x)))(a), [[]])
compose(map(sum), powerSet)([1, 2, 3, 4, 5])
```

```
[ 0,
5,
4,
9,
3,
8,
7,
12,
2,
7,
6,
11,
5,
10,
9,
14,
1,
6,
5,
10,
4,
9,
8,
13,
3,
8,
7,
12,
6,
11,
10,
15 ]
```

@mrosata welcome =)

thanks

powerSet is doing something similar to

`lift2`

right?
@mrosata almost, as u can see I don't use

`filterM`

@mrosata

`filterM`

more powerful
@ram-bot

```
const powerSet2 = compose(map(flatten), traverse(of, x => [x, []]))
compose(map(sum), powerSet2)([1, 2, 3, 4, 5])
```

```
[ 15,
10,
11,
6,
12,
7,
8,
3,
13,
8,
9,
4,
10,
5,
6,
1,
14,
9,
10,
5,
11,
6,
7,
2,
12,
7,
8,
3,
9,
4,
5,
0 ]
```

@mrosata or

`const powerSet2 = compose(map(filter(Boolean)), traverse(of, x => [x, undefined]))`

@xgrommx I see in your earlier usage of max product of 3 elements as well as in your powerSet implementation, you are using

`ap`

without a list of functions as in `ap(flip(objOf), product)([2,3,4])`

@ram-bot

`traverse(of, x => [x, undefined])([1,2,3])`

```
[ [ 1, 2, 3 ],
[ 1, 2, undefined ],
[ 1, undefined, 3 ],
[ 1, undefined, undefined ],
[ undefined, 2, 3 ],
[ undefined, 2, undefined ],
[ undefined, undefined, 3 ],
[ undefined, undefined, undefined ] ]
```

how is

`ap`

working here with functions as args instead of an array of functions?
@bijoythomas applicative version for function

@bijoythomas

`S = f => g => x => f(x)(g(x))`

@bijoythomas do u understand it?)

I've used mostly

`lift`

so I understand `lift(inc)(Just(5))`

and I would have written the `ap(flip(objOf), product)([2,3,4])`

as `lift(objOf)(product)(identity)([2,3,4])`

.. but no .. sorry .. I don't understand your `ap`

usage
@bijoythomas

`lift(inc)(Just 5)`

=> `map(inc)(Just 5)`

right .. so that's just the functor map right?

@bijoythomas in my case - no

@bijoythomas

`ap(flip(objOf), product)`

=> `ap = f => g => x => f(x)(g(x))`

=> `f = flip(objOf), g = product`

=> `(flip(objOf)(x))(product(x))`

=> `objOf(product(x), x)`

yes .. I see how when substituting in the equations .. it does make sense

`lift(objOf)(product)(identity)`

is equal to `objOf(product(x), x)`

also .. yes? .. is there a reason to use one over the other? what is there is more than one argument?
@bijoythomas strange using for

`lift`

@xgrommx yes .. I think my understanding of

`lift`

has me using it in places where it's not really meant to be used
Go for the latter in most cases. The former works because

`Function`

is an applicative - this particular pattern also gets called the `S`

combinator in other places. There are some really neat examples (e.g. `average = lift(divide, sum, length)`

but I’d restrict your usage to situations where it almost reads as its implementation (e.g. “average = divide sum (by) length”)
Thanks @xgrommx and @i-am-tom

I didn't know that was the S combinator

I didn't know that was the S combinator

Ok .. took a break and went back to LYAH and I think I got my fp aha moment today w.r.t functions as applicatives :-) .. so for applicatives, we need to extract a function in a 'Box' and apply it to a value in a 'Box' for the type (-> r) we need a function from r to extract a function, and another function from r to extract the value and apply the extracted function to the extracted value .. so in

`ap(f,g)(x)`

, f(x) is the extracted function being applied to g(x) which is the extracted value.
since f applied to x returns another function .. well .. that's why f is a binary function

It’s probably a better intuition to say Applicative (specifically Apply) is about *merging* “boxes”, rather than taking something out and putting it into the other

ah ok

but yeah:

`ap :: f (a -> b) -> f a -> f b`

. If our `f`

is `((->) r)`

, we get `ap :: ((->) r) (a -> b) -> ((->) r) a -> ((->) r) b`

, which we can simplify to `ap :: (r -> a -> b) -> (r -> a) -> (r -> b)`

but `lift`

is the friend here, and its signature is much more useful: `lift2 :: Apply f => (a -> b -> c) -> f a -> f b -> f c`

=> `lift2 :: (a -> b -> c) -> ((->) r) a -> ((->) r) b -> ((->) r) c`

, which simplifies to:

`lift2 :: (a -> b -> c) -> (r -> a) -> (r -> b) -> r -> c`

… which I think clears it up a lot

(That last type signature, I mean - not the wall of monospace letters and symbols, hah)

Yes .. that clearly explains my usage of

`lift(objOf)(product)(identity)`

.. thanks
:)

:smile:

Now to move on to your implementation of filterM @xgrommx :-)

@bijoythomas you should put some coffee on for that one :smile:

oh absolutely @mrosata .. I had to play with it in the REPL for a while before I realized the lift was doing list comprehension

I spent some time in the repl with it last night w/the js

`filterM`

, then today followed along a post where someone else implemented `filterM`

in Haskell. That helped a lot, though I do feel like when I sit down to break apart how the JavaScript version works I'll probably end up spending an equal amount of time figuring it out.
:smile: