These two Scalaz types
scalaz.concurrent.Task[+A]
scalaz.effect.IO[A]
seem very conceptually similar. They both:
- Represent a potentially side-effecting computation
- Produce a success (
A
) or failure (Exception
) result
- Have
Monad
instances
- Can be unsafely unwrapped with
run
or unsafePerformIO
How do they differ? Why do they both exist?
Core difference is that IO simply delays the execution of something but does it within a current thread. Task on the other hand is capable of executing something concurrently (thus the implicit ExecutorService).
Additionally, Task carries the semantics of scalaz's Future (Future that is more compossible than the classic scala version; Future that allows you to have higher control of concurrency by making forking explicitly defined and not execute tasks in parallel as soon as instantiated ). Furthermore, if you read the source for scalaz's Future it will point you to Task as a more robust version that can be used in prod.
Finally, note that attemptRun of the Task returns \/[Throwable, A] while unsafePerformIO of IO just returns A. This speaks to more robust treatment of real life error scenarios.
As far as I know, everywhere you would use IO to compose effects you would use Task in real production codebase.
Here is a good blog post about Task usage: Tim Perrett's Task Post