4

I have 3 functions, f1, f2, f3.

f1 and f3 are sync and return Option<string> but f2 is an async function return Promise<Option<string>>.

How should I use these three functions in a single pipe?

Here is my code:

import {some, chain} from 'fp-ts/lib/Option';
import {pipe} from 'fp-ts/lib/pipeable';

const f1 = (input: string) => {
    return some(input + " f1")
};
const f2 = async (input: string) => {
    return some(input + " f2")
};
const f3 = (input: string) => {
    return some(input + " f3");
};

const result = pipe(
    "X",
    f1,
    chain(f2),
    chain(f3),
);

console.log("result", result);
mohsen saremi
  • 685
  • 8
  • 22
  • You have two nested effects (asynchronous and optional) so you need to compose two monads. Since monads don't compose mechanically you have to use monad transformers. I am sure FP-TS supplies `OptionT`. –  Dec 30 '19 at 09:19
  • Yes there is `OptionT` in FP-TS but I didn't understand how should I use it. Can you show me how can I use `OptionT` in above sample code? Thanks. – mohsen saremi Dec 30 '19 at 10:24
  • I wasn't aware of the [fp-ts library](https://gcanti.github.io/fp-ts/). Very interesting. – karmakaze Dec 31 '19 at 02:37
  • please read its docs and help me solve my problem – mohsen saremi Dec 31 '19 at 04:48

1 Answers1

8

I found a solution using TaskOption

Here is my code:

import * as O from 'fp-ts/lib/Option';
import * as TO from 'fp-ts-contrib/lib/TaskOption';
import {pipe} from 'fp-ts/lib/pipeable';
import {flow} from 'fp-ts/lib/function';

const f1 = (input: string): O.Option<string> => {
    return O.some(input + " f1")
};
const f2 = (input: string): TO.TaskOption<string> => async () => {
    return O.some(input + " f2")
};
const f3 = (input: string): O.Option<string> => {
    return O.some(input + " f3");
};

pipe(
    "X",
    flow(f1, TO.fromOption),
    TO.chain(f2),
    TO.chain(flow(f3,TO.fromOption)),
)().then(console.log);

We convert all of Options to TaskOptions using TO.fromOption.

mohsen saremi
  • 685
  • 8
  • 22