1

Suppose that you have the following code:

import R from "ramda";
import S from "sanctuary";
import { Left, Right } from "sanctuary-either";

const add = R.curry((p1, p2) => p1 + p2);
const addOne = add(1);

const func1 = () => Right(2);
const func2 = () => Right(7);

Combining addOne with func1 or func2 is relatively easy:

const res = R.compose(
  S.map(addOne),
  func1
)(); 

but how can one call add using func1 and func2 as arguments?

p.s. I know that ramda offers an add function. Consider the example as an abstraction of a real world problem.

antoniom
  • 3,143
  • 1
  • 37
  • 53

1 Answers1

5

You are probably looking for the lift2 function:

const addEithers = S.lift2(add)

console.log(addEithers(func1())(func2()))

Alternatively, you can use ap:

S.ap(S.map(add)(func1()))(func2())
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Are you sure that this can be applied on an `Either`? I am getting a weird error "TypeError: ‘lift2’ applied to the wrong number of arguments". And the documentation states that it applies on `Apply`s. Same error for the `S.ap` as well – antoniom Mar 21 '20 at 21:40
  • 2
    Yes, [`Either` implements `Apply`](https://github.com/sanctuary-js/sanctuary-either/tree/v2.1.0). I guess the currying is not optional in Sanctuary, and one needs to make two calls instead of passing two arguments? See the edit. – Bergi Mar 21 '20 at 21:44
  • Ramda's [`lift`](https://ramdajs.com/docs/#lift) is similar; the currying is similarly mandatory. – Scott Sauyet Mar 21 '20 at 23:44
  • 1
    @ScottSauyet The ramda docs you linked show a signature of `R.lift(add)(someEither, anotherEither)` not `R.lift(add)(someEither)(anotherEither)`, so it looks like `lift` is *not* completely curried but the partial application is optional? – Bergi Mar 22 '20 at 11:07
  • @Bergi: sorry, you're right. I should never go by memory even on a library I maintain! – Scott Sauyet Mar 22 '20 at 23:03