Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chainTaskOptionKW #1744

Merged
merged 2 commits into from
Aug 22, 2022
Merged

Conversation

AmirabbasJ
Copy link
Contributor

@AmirabbasJ AmirabbasJ commented Aug 20, 2022

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>

Copy link
Contributor

@samhh samhh left a comment

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
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
Copy link
Owner

gcanti commented Aug 22, 2022

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

src/TaskEither.ts Show resolved Hide resolved
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