Skip to content

feat: add chainTaskOptionKW#1744

Merged
gcanti merged 2 commits into
gcanti:masterfrom
AmirabbasJ:add-chainTaskOptionKW
Aug 22, 2022
Merged

feat: add chainTaskOptionKW#1744
gcanti merged 2 commits into
gcanti:masterfrom
AmirabbasJ:add-chainTaskOptionKW

Conversation

@AmirabbasJ

@AmirabbasJ AmirabbasJ commented Aug 20, 2022

Copy link
Copy Markdown
Contributor

if we wanted to chain a function which returns TaskOption in a TaskEither pipeline we would have to do

import * as TE from 'fp-ts/TaskEither'
import * as TO from 'fp-ts/TaskOption'

declare const fooTaskEither: TE.TaskEither<'no', number>;
declare const getTaskOption: (x: number) => TO.TaskOption<boolean>;

const x = pipe(
  fooTaskEither,
  TE.chainW(TE.fromTaskOptionK(() => 'big no' as const)(getTaskOption)),
);

// x : TE.TaskEither<'big no' | 'no', boolean>

but I thought it would be a better idea if we could do this instead:

const x = pipe(
  fooTaskEither,
  chainTaskOptionKW(() => 'big no' as const)(getTaskOption),
);

// x : TE.TaskEither<'big no' | 'no', boolean>

@samhh samhh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If chainTaskOptionK is defined in terms of chainTaskOptionKW then we can drop the any assertion:

diff --git a/src/TaskEither.ts b/src/TaskEither.ts
index 3adaf404..82b3d56b 100644
--- a/src/TaskEither.ts
+++ b/src/TaskEither.ts
@@ -431,21 +431,22 @@ export const fromTaskOptionK = <E>(
 
 /**
  * @category combinators
- * @since 2.11.0
  */
-export const chainTaskOptionK = <E>(
-  onNone: Lazy<E>
-): (<A, B>(f: (a: A) => TaskOption<B>) => (ma: TaskEither<E, A>) => TaskEither<E, B>) =>
-  flow(fromTaskOptionK(onNone), chain)
+export const chainTaskOptionKW = <E2>(
+  onNone: Lazy<E2>
+) => <A, B>(
+  f: (a: A) => TaskOption<B>
+) => <E1>(ma: TaskEither<E1, A>): TaskEither<E1 | E2, B> =>
+  pipe(ma, chain(fromTaskOptionK<E1 | E2>(onNone)(f)))
 
 /**
  * @category combinators
+ * @since 2.11.0
  */
-export const chainTaskOptionKW: <E2>(
-  onNone: Lazy<E2>
-) => <A, B>(
-  f: (a: A) => TaskOption<B>
-) => <E1>(ma: TaskEither<E1, A>) => TaskEither<E1 | E2, B> = chainTaskOptionK as any
+export const chainTaskOptionK: <E>(
+  onNone: Lazy<E>
+) => (<A, B>(f: (a: A) => TaskOption<B>) => (ma: TaskEither<E, A>) => TaskEither<E, B>) =
+  chainTaskOptionKW
 
 /**
  * @category combinators

@AmirabbasJ

Copy link
Copy Markdown
Contributor Author

@samhh hmm, that's a good point, if you see it fit and everything is ok go ahead and merge that, cause I'm not really familiar with the codebase too

but I'm wondering, in general, is the fact the we don't assert the only benefit that we get?
the reason I did that was that when I looked at the other weak combinators, I saw a pattern (the weak ones are just asserted version of the non-weak ones) so I thought maybe it's a convention of some sort?

@gcanti

gcanti commented Aug 22, 2022

Copy link
Copy Markdown
Owner

I saw a pattern (the weak ones are just asserted version of the non-weak ones)

That's when the weak non-weak ones are derived, example (from TaskEither.ts):

// derived
export const chainEitherK: <E, A, B>(f: (a: A) => E.Either<E, B>) => (ma: TaskEither<E, A>) => TaskEither<E, B> =
  chainEitherK_(FromEither, Chain)

// asserted version
export const chainEitherKW: <E2, A, B>(
  f: (a: A) => Either<E2, B>
) => <E1>(ma: TaskEither<E1, A>) => TaskEither<E1 | E2, B> = chainEitherK as any

Comment thread src/TaskEither.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants