# Task.map2 and independent asynchronous operations

**URL:** https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471
**Category:** Request Feedback
**Created:** [November 7, 2018, 1:35pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471 "2018-11-07T13:35:02Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![minedeljkovic](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/minedeljkovic/32/1530_2.png) [@minedeljkovic](https://discourse.elm-lang.org/u/minedeljkovic)
#### Post date: [November 7, 2018, 1:35pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/1 "2018-11-07T13:35:02Z")

</div>

According to current documentation, `Task.map2` (and other mapN functions) combine tasks such that they “run in order so the first task will be completely finished before the second task starts”. In general, such constraint is not imposed by type of this function, i.e. the same function could have semantics to run provided tasks in parallel.

Are these current semantics intentional? Or is this, maybe, constrained by the [WIP Process library (section Future Plans)](https://package.elm-lang.org/packages/elm/core/latest/Process) in which case it would be reconsidered once the Process library reaches stability? Is it possible to implement `(a -> b -> result) -> Task x a -> Task x b -> Task x result` function type, with parallel semantics, without relying on native code, right now?

Related issues:

> <https://github.com/elm/http/issues/28>

  

> <https://github.com/rtfeldman/elm-spa-example/issues/14>

### Warning! Reference to Haskell-like FP abstractions ahead. If you are not interested in this kind of content, please skip reading.

`Task` could be seen as an instance of `Applicative` typeclass, and `map2` function could be implementation of `liftA2` function type. In general, `Applicative` describes combining independent computations, so in case of `Task` that would mean running asynchronous processes in parallel. For example [Task from the Monix scala library](https://monix.io/docs/2x/eval/task.html#the-applicative-zip2-zip3--zip6) is an instance of `Applicative`, and it’s function family zipMapN have parallel semantics.  
I believe parallel semantics of `Task.map2` function would be more inline with similar abstractions in FP community.

---

<div class="post-metadata">

### Author: ![Brian\_Carroll](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian_carroll/32/444_2.png) [@Brian\_Carroll](https://discourse.elm-lang.org/u/Brian_Carroll)
#### Post date: [November 7, 2018, 3:23pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/2 "2018-11-07T15:23:26Z")

</div>

If you look at the source code for `Task.map2` you’ll see that it’s built on top of `Task.andThen`, which is known as the monadic `bind` or `>>=` in Haskell.

So it already _is_ an applicative. It’s just that the semantics of `andThen` are sequential.

Elm does have monads and applicatives but tends to focus on how to use individual instances of those rather than pushing people to learn the full general concept before starting to get things done. An applicative in Elm is “a type that has `map2`, `map3` etc.”

However `Cmd.batch` doesn’t have sequential semantics so you can use that instead.

---

<div class="post-metadata">

### Author: ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)
#### Post date: [November 7, 2018, 3:30pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/3 "2018-11-07T15:30:50Z")

</div>

> [@minedeljkovic](#):
>
> I believe parallel semantics of `Task.map2` function would be more inline with similar abstractions in FP community.

Task is roughly equivalent to `IO` in Haskell. Looking at the `IO` instance that defines `liftA2` [here](http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#line-1353), you see that it is sequential there as well (`liftA2 = liftM2`). **This is because `Task` and `IO` are both general to all kinds of effects.** Having things go in parallel is often acceptable for HTTP, but it would be quite a problem for reading/writing files.

Adding a way to run tasks in parallel may be nice, but having it be the default for `map2` means that a `Task` will be quite confusing if it is ever used for effects that are not naturally independent. (And even with HTTP, it is not always the case that requests are independent!)

---

<div class="post-metadata">

### Author: ![Dan\_Abrams](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dan_abrams/32/3171_2.png) [@Dan\_Abrams](https://discourse.elm-lang.org/u/Dan_Abrams)
#### Post date: [November 7, 2018, 3:36pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/4 "2018-11-07T15:36:01Z")

</div>

Is there a way to map two independent HTTP requests that are done in parallel, then return a Msg currently? I have a use case for that where they really can and should be parallel, if possible.

---

<div class="post-metadata">

### Author: ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)
#### Post date: [November 7, 2018, 4:02pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/5 "2018-11-07T16:02:11Z")

</div>

The path for now is to use two different commands.

It is conceivable that there should be an abstraction for HTTP that accounts for parallel requests that should happen together, but it then becomes much more complicated to (1) track errors and (2) track progress. I have tried to do it, but to fully account for these kinds of situations, I have found that it complicates the simple cases quite a bit. My current feeling is that it might want an abstraction of its own, and the starting point there is to get a couple real examples where people feel this might be the best path.

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [November 17, 2018, 4:02pm UTC](https://discourse.elm-lang.org/t/task-map2-and-independent-asynchronous-operations/2471/6 "2018-11-17T16:02:23Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
