thunk v0.3.1 Thunk View Source
Laziness in Elixir. Thunks are computations that have not yet happened. This module provides the thunk type and functions for manipulating and creating thunks.
Thunks allow for setting up a computation and transforming it without evaluating it. A thunk can be used by other thunks and evaluation is shared.
Example
defmodule Infinity do
require Thunk
@doc """
An infinite list that just repeats its argument.
## Example
iex> xs = Infinity.repeatedly(1)
#Thunk<...>
iex> [h | t] = Thunk.force(xs)
[1 | #Thunk<...>]
"""
def repeatedly(x) do
Thunk.suspend([x | repeatedly(x)])
end
end
Link to this section Summary
Functions
Given a thunk with a function and a thunk with it’s argument, returns a thunk with the result of their application
Copies a thunk. When a thunk is forced it ceases to exist, so this function is useful for holding onto a result should it be forced
Deletes a thunk, to be used if the thunk does not need to ever be evaluated
Is thunk still around?
Forces a thunk. Raises a ThunkError if already forced or deleted
Applies a function to a thunk
Suspends a value in a thunk. Doesn’t evaluate it’s argument. Can be used as a do block as well
Is value a thunk?
Link to this section Types
Alias for any.
Thunk type.
Link to this section Functions
Given a thunk with a function and a thunk with it’s argument, returns a thunk with the result of their application.
Example
iex> defmodule ThunkyMath do
...> require Thunk
...>
...> # Add two thunks
...> def add(x, y) do
...> addr = fn n1 -> fn n2 -> n1 + n2 end end
...> Thunk.map(x, addr)
...> |> Thunk.apply(y)
...> end
...> end
iex> x = Thunk.suspend(12)
iex> y = Thunk.suspend(13)
iex> z = ThunkyMath.add(x, y)
#Thunk<...>
iex> Thunk.force(z)
25
Copies a thunk. When a thunk is forced it ceases to exist, so this function is useful for holding onto a result should it be forced.
Example
iex> thunk = Thunk.suspend(:some_computation)
iex> thunk_copy = Thunk.copy(thunk)
iex> Thunk.force(thunk)
iex> Thunk.exists?(thunk)
false
iex> Thunk.force(thunk_copy)
:some_computation
Deletes a thunk, to be used if the thunk does not need to ever be evaluated.
Example
iex> thunk = Thunk.suspend(:some_computation)
iex> Thunk.delete(thunk)
iex> Thunk.exists?(thunk)
false
Is thunk still around?
Forces a thunk. Raises a ThunkError if already forced or deleted.
Example
iex> thunk = Thunk.suspend(:value)
iex> Thunk.force(thunk)
:value
Applies a function to a thunk.
Example
iex> thunk_x = Thunk.suspend(1)
iex> thunk_y = Thunk.map(thunk_x, fn x -> x + 1 end)
iex> Thunk.force(thunk_y)
2
Suspends a value in a thunk. Doesn’t evaluate it’s argument. Can be used as a do block as well.
Example
iex> Thunk.suspend(raise("Oops you evaluated me!"))
#Thunk<...>
iex> Thunk.suspend do
...> x = 5
...> y = 6
...> x + y
...> end
#Thunk<...>
Is value a thunk?