Fp-ts: Question on using flow.

Created on 13 Dec 2019  路  10Comments  路  Source: gcanti/fp-ts

Question

Current Behavior

I can't understand why the following code doesn't work. The types all seem to be correct

const likeArticle = flow(
  api.likeArticle,
  setArticleLike,
  chain(updateLikedArticlesCount)
);

The above functions have the following signatures:

likeArticle: (id?: number | undefined) => TaskEither<undefined, number>
const setArticleLike: (ma: TaskEither<undefined, number>) => TaskEither<undefined, Article>
chain<undefined, Article, Article>(f: (a: Article) => TaskEither<undefined, Article>): (ma: TaskEither<undefined, Article>) => TaskEither<undefined, Article>
updateLikedArticlesCount: (article: Article) => TaskEither<undefined, Article>

I am trying to call it as likeArticle(1) for example but all it returns is a chain function rather than a TaskEither.

I can use pipe as follows:

const likeArticle = (id?: number) =>
  pipe(api.likeArticle(id), setArticleLike, chain(updateLikedArticlesCount))();

But seems like I should be able to pass id into the pipe someway rather than needing this outside wrapping function.

Most helpful comment

@rikbrowning FYI you can use declare in order to write a repro:

import { flow } from 'fp-ts/lib/function'
import { chain, TaskEither } from 'fp-ts/lib/TaskEither'

type Article = string

declare const likeArticle: (id?: number) => TaskEither<undefined, number>
declare const setArticleLike: (ma: TaskEither<undefined, number>) => TaskEither<undefined, Article>
declare const updateLikedArticlesCount: (article: Article) => TaskEither<undefined, Article>

// program: (id?: number) => TaskEither<undefined, string>
const program = flow(likeArticle, setArticleLike, chain(updateLikedArticlesCount))

All 10 comments

@rikbrowning FYI you can use declare in order to write a repro:

import { flow } from 'fp-ts/lib/function'
import { chain, TaskEither } from 'fp-ts/lib/TaskEither'

type Article = string

declare const likeArticle: (id?: number) => TaskEither<undefined, number>
declare const setArticleLike: (ma: TaskEither<undefined, number>) => TaskEither<undefined, Article>
declare const updateLikedArticlesCount: (article: Article) => TaskEither<undefined, Article>

// program: (id?: number) => TaskEither<undefined, string>
const program = flow(likeArticle, setArticleLike, chain(updateLikedArticlesCount))

@gcanti TIL, that's really cool. Sorry you'll have to forgive my ignorance

@rikbrowning no problem, that's kind of a hack but it works well.

Back to this issue, can we close it? looks like program has the expected type.

@gcanti it has the expected type but when I execute it I get back function chain rather than a TaskEither?

Weird, if I add the implementations I can see the expected result

import { flow } from 'fp-ts/lib/function'
import { chain, right, TaskEither } from 'fp-ts/lib/TaskEither'

type Article = string

const likeArticle = (_id?: number): TaskEither<undefined, number> => right(1)
const setArticleLike = (_ma: TaskEither<undefined, number>): TaskEither<undefined, Article> => right('a')
const updateLikedArticlesCount = (article: Article): TaskEither<undefined, Article> => right(article)

flow(likeArticle, setArticleLike, chain(updateLikedArticlesCount))(1)().then(console.log)
// { _tag: 'Right', right: 'a' }

flow(likeArticle, setArticleLike, chain(updateLikedArticlesCount))(1)() is that not the equivalent of program(1)()? Is there no way to have the call behave as program(1) without extra function call? Ideally I want to expose the flow function to accept the ID without having to the wrapper.

After some more reading, is the extra () required to execute the TaskEither?

is the extra () required to execute the TaskEither?

Yes if you want to get back a promise, TaskEither<E, A> is just an alias of () => Promise<Either<E, A>>

Awesome, that's the part that was confusing me

It should be explained in the documentation why IO, Task, TaskEither need to be called. Something like: Side-effect composition can be called now or later. In FP, we split definition from execution. Am I correct?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

denistakeda picture denistakeda  路  4Comments

mmkal picture mmkal  路  3Comments

steida picture steida  路  4Comments

vicrac picture vicrac  路  4Comments

FruitieX picture FruitieX  路  3Comments