elm-lang/core/3.0.0

NOTE: this package moved to elm/core

NOTE: this package is not compatible with Elm 0.19.1

Task

Tasks make it easy to describe asynchronous operations that may fail, like HTTP requests or writing to a database. For more information, see the Elm documentation on Tasks.

Basics

type Task x a

Represents asynchronous effects that may fail. It is useful for stuff like HTTP.

For example, maybe we have a task with the type (Task String User). This means that when we perform the task, it will either fail with a String message or succeed with a User. So this could represent a task that is asking a server for a certain user.

succeed : a -> Task x a

A task that succeeds immediately when run.

succeed 42    -- results in 42
fail : x -> Task x a

A task that fails immediately when run.

fail "file not found" : Task String a

Mapping

map : (a -> b) -> Task x a -> Task x b

Transform a task.

map sqrt (succeed 9) == succeed 3
map2 : (a -> b -> result) -> Task x a -> Task x b -> Task x result

Put the results of two tasks together. If either task fails, the whole thing fails. It also runs in order so the first task will be completely finished before the second task starts.

map2 (+) (succeed 9) (succeed 3) == succeed 12
map3 : (a -> b -> c -> result) -> Task x a -> Task x b -> Task x c -> Task x result
(a -> b -> c -> d -> result)
-> Task x a
-> Task x b
-> Task x c
-> Task x d
-> Task x result
(a -> b -> c -> d -> e -> result)
-> Task x a
-> Task x b
-> Task x c
-> Task x d
-> Task x e
-> Task x result
andMap : Task x (a -> b) -> Task x a -> Task x b

Put the results of two tasks together. If either task fails, the whole thing fails. It also runs in order so the first task will be completely finished before the second task starts.

This function makes it possible to chain tons of tasks together and pipe them all into a single function.

(f `map` task1 `andMap` task2 `andMap` task3) == map3 f task1 task2 task3

Chaining

andThen : Task x a -> (a -> Task x b) -> Task x b

Chain together a task and a callback. The first task will run, and if it is successful, you give the result to the callback resulting in another task. This task then gets run.

succeed 2 `andThen` (\n -> succeed (n + 2)) == succeed 4

This is useful for chaining tasks together. Maybe you need to get a user from your servers and then lookup their picture once you know their name.

sequence : List (Task x a) -> Task x (List a)

Start with a list of tasks, and turn them into a single task that returns a list. The tasks will be run in order one-by-one and if any task fails the whole sequence fails.

sequence [ succeed 1, succeed 2 ] == succeed [ 1, 2 ]

This can be useful if you need to make a bunch of HTTP requests one-by-one.

Errors

onError : Task x a -> (x -> Task y a) -> Task y a

Recover from a failure in a task. If the given task fails, we use the callback to recover.

fail "file not found" `onError` (\msg -> succeed 42) -- succeed 42
succeed 9 `onError` (\msg -> succeed 42)             -- succeed 9
mapError : (x -> y) -> Task x a -> Task y a

Transform the error value. This can be useful if you need a bunch of error types to match up.

type Error = Http Http.Error | WebGL WebGL.Error


getResources : Task Error Resource
getResources =
  sequence [ mapError Http serverTask, mapError WebGL textureTask ]
toMaybe : Task x a -> Task never (Maybe a)

Translate a task that can fail into a task that can never fail, by converting any failure into Nothing and any success into Just something.

toMaybe (fail "file not found") == succeed Nothing
toMaybe (succeed 42)            == succeed (Just 42)

This means you can handle the error with the Maybe module instead.

fromMaybe : x -> Maybe a -> Task x a

If you are chaining together a bunch of tasks, it may be useful to treat a maybe value like a task.

fromMaybe "file not found" Nothing   == fail "file not found"
fromMaybe "file not found" (Just 42) == succeed 42
toResult : Task x a -> Task never (Result x a)

Translate a task that can fail into a task that can never fail, by converting any failure into Err something and any success into Ok something.

toResult (fail "file not found") == succeed (Err "file not found")
toResult (succeed 42)            == succeed (Ok 42)

This means you can handle the error with the Result module instead.

fromResult : Result x a -> Task x a

If you are chaining together a bunch of tasks, it may be useful to treat a result like a task.

fromResult (Err "file not found") == fail "file not found"
fromResult (Ok 42)                == succeed 42

Threads

spawn : Task x a -> Task y ThreadID

Run a task on a separate thread. This lets you start working with basic concurrency. In the following example, task1 and task2 will be interleaved. If task1 makes a long HTTP request, we can hop over to task2 and do some work there.

spawn task1 `andThen` \_ -> task2
sleep : Time -> Task x ()

Make a thread sleep for a certain amount of time. The following example sleeps for 1 second and then succeeds with 42.

sleep 1000 `andThen` \_ -> succeed 42

Abstract type that uniquely identifies a thread.