Skip to content

Option.mapEffect #3142

Closed
Closed
@jamesbirtles

Description

@jamesbirtles

What is the problem this feature would solve?

Given an Option<A> and a fn (a: A) => Effect<B, E, R> it would be useful to have a function that could apply that fn to the Some value and return an Effect<Option<B>, E, R> rather than an Option<Effect<B, E, R>> as Option.map would so that it can more easily be used in an effect pipeline.

This is a pattern I am coming across a few times when, for example, decoding from a database query where the potential for a missing row is represented as an Option

What is the feature you are proposing to solve the problem?

Option.mapEffect seems like a fairly obvious api for this I think, I have made my own function to do this:

import { Effect, Option } from 'effect';
import { dual } from 'effect/Function';

export const mapEffect: {
	<B, A, E, R>(
		f: (a: A) => Effect.Effect<B, E, R>,
	): (self: Option.Option<A>) => Effect.Effect<Option.Option<B>, E, R>;
	<B, A, E, R>(
		self: Option.Option<A>,
		f: (a: A) => Effect.Effect<B, E, R>,
	): Effect.Effect<Option.Option<B>, E, R>;
} = dual(2, <B, A, E, R>(self: Option.Option<A>, f: (a: A) => Effect.Effect<B, E, R>) =>
	Option.match(self, {
		onSome: (value) => Effect.map(f(value), Option.some),
		onNone: () => Effect.succeedNone,
	}),
);

What alternatives have you considered?

  • Using my own wrapper as posted
  • Using no wrapper and just writing out the relatively verbose Effect.andThen(Option.match( ... ))
  • A more generic 'transpose' function (as rust calls it) that would take Option<Effect<A, E, R>> and turn it into Effect<Option<A>, E, R>. Then you could use the existing option map in a pipeline like: (..., Effect.map(Option.map(fn)), Effect.andThen(Option.transpose). I think this would be super useful and am slightly surprised I couldn't find a similar function in effect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions