# Sequencing dependent computations

beginner

## Sequencing an effect that depends on another

#### Problem

I have:

• A value of type `F<A>`.
• A function of type `(A) -> F<B>`.

I want to have:

• A value of type `F<B>`.

#### Solution

In order to have a value of `F<B>` we need to run the provided function, but we need an input for it. This input may be obtained from `F<A>`, but the type does not match with the requirement of the function.

Fortunately, we have the `flatMap` function, present in the Monad type class. It will be able to access the internals of the effect, and feed the value to the provided function.

#### Example

Consider the following value and function:

``````let conferenceOption = Option.some(Conference(title: "WWDC"))

// Provides the next talk for a Conference, if it exists.
func nextTalk(at conference: Conference) -> Option<Talk>
``````

The function `nextTalk` lets us retrieve the next talk for a given conference. However, we do not have a conference itself, but an `Option<Conference>`. We can use the `flatMap` operation to achieve our goal:

``````let talkOption = conferenceOption.flatMap { conference in
nextTalk(at: conference)
}
``````

## Sequencing two effects

#### Problem

I have:

• A value of type `F<A>`.
• A value of type `F<B>`.

I want to have:

• A value of type `F<B>`, which should be run only if `F<A>` is successful.

#### Solution

We could use the `flatMap` operation here by providing a function that ignores the input and yields the constant value of type `F<B>`. However, the Monad type class provides a convenience function called `followedBy` that takes a constant value instead of a function, and has the same semantics as `flatMap`.

#### Example

This function can be useful when we want to apply an effect conditionally after successfully applying another one. An example of this could be printing a message to the console when another effect finishes successfully:

``````// Performs a network call, returning an error or the content of the response
func networkCall() -> IO<Error, String>
``````
``````let program: IO<Error, Void> = networkCall()
.followedBy(ConsoleIO.print("Finished successfully"))^
``````

This provides a single `IO<Error, Void>` that will print the message if the network call finishes successfully, and will not print anything in case the network call fails with an error.

## Sequencing two effects, keeping the result of the first

#### Problem

I have:

• A value of type `F<A>`.
• A function of type `(A) -> F<B>`.

I want to have:

• A value of type `F<A>`, but performing the effect given by the function.

#### Solution

The `followedBy` function does not let us access the results of the previous effect, or return it as a result. If we want to do that, the Monad type class provides the `flatTap` function. Its behavior is like `flatMap`, but disregarding the result of the second effect and keeping the first.

#### Example

The `flatTap` operation is useful, for instance, to print some log messages. Using the previous network call example:

``````let loggedResponse: IO<Error, String> = networkCall()
.flatTap { response in
ConsoleIO.print("Response from call: \(response)")
}^
``````

This way, the log is executed if the network call is successful, and still lets us chain other operations to work with its response.