This is an alternative site for discovering Elm packages.
You may be looking for the
official Elm package site
instead.

This library lets you delay a computation until later.

type Lazy a
= Lazy (() -> a)
| Evaluated a

A wrapper around a value that will be lazily evaluated.

lazy : (() -> a) -> Lazy a

Delay the evaluation of a value until later. For example, maybe we will need to generate a very long list and find its sum, but we do not want to do it unless it is absolutely necessary.

```
lazySum : Lazy Int
lazySum =
lazy (\() -> sum <| List.range 1 1000000 )
```

Now we only pay for `lazySum`

if we actually need it.

force : Lazy a -> a

Force the evaluation of a lazy value. This means we only pay for the computation when we need it. Here is a rather contrived example.

```
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
sums : (Int, Int, Int)
sums =
(force lazySum, force lazySum, force lazySum)
```

evaluate : Lazy a -> Lazy a

Evaluate the lazy value if it has not already been evaluated. If it has, do nothing.

```
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
sums : (Int, Int, Int)
sums =
let
evaledSum =
evaluate lazySum
in
(force evaledSum, force evaledSum, force evaledSum)
```

This is mainly useful for cases where you may want to store a lazy value as a
lazy value and pass it around. For example, in a list. Where possible, it is better to use
`force`

and simply store the computed value seperately.

map : (a -> b) -> Lazy a -> Lazy b

Lazily apply a function to a lazy value.

```
lazySum : Lazy Int
lazySum =
map List.sum (lazy (\() -> <| List.range 1 1000000)
```

The resulting lazy value will create a big list and sum it up when it is finally forced.

map2 : (a -> b -> result) -> Lazy a -> Lazy b -> Lazy result

Lazily apply a function to two lazy values.

```
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
lazySumPair : Lazy (Int, Int)
lazySumPair =
map2 (,) lazySum lazySum
```

map3 : (a -> b -> c -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy result

map4 : (a -> b -> c -> d -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy d -> Lazy result

map5 : (a -> b -> c -> d -> e -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy d -> Lazy e -> Lazy result

apply : Lazy (a -> b) -> Lazy a -> Lazy b

Lazily apply a lazy function to a lazy value. This is pretty rare on its own, but it lets you map as high as you want.

```
map3 f a b == f `map` a `apply` b `apply` c
```

It is not the most beautiful, but it is equivalent and will let you create
`map9`

quite easily if you really need it.

andThen : (a -> Lazy b) -> Lazy a -> Lazy b

Lazily chain together lazy computations, for when you have a series of steps that all need to be performed lazily. This can be nice when you need to pattern match on a value, for example, when appending lazy lists:

```
type List a = Empty | Node a (Lazy (List a))
cons : a -> Lazy (List a) -> Lazy (List a)
cons first rest =
Lazy.map (Node first) rest
append : Lazy (List a) -> Lazy (List a) -> Lazy (List a)
append lazyList1 lazyList2 =
let
appendHelp list1 =
case list1 of
Empty ->
lazyList2
Node first rest ->
cons first (append rest list2))
in
lazyList1
|> Lazy.andThen appendHelp
```

By using `andThen`

we ensure that neither `lazyList1`

or `lazyList2`

are forced
before they are needed. So as written, the `append`

function delays the pattern
matching until later.

```
module Lazy
exposing
( Lazy
, force
, lazy
, evaluate
, map
, map2
, map3
, map4
, map5
, apply
, andThen
)
{-| This library lets you delay a computation until later.
# Basics
@docs Lazy, lazy, force, evaluate
# Mapping
@docs map, map2, map3, map4, map5
# Chaining
@docs apply, andThen
-}
-- PRIMITIVES
{-| A wrapper around a value that will be lazily evaluated.
-}
type Lazy a
= Lazy (() -> a)
| Evaluated a
{-| Delay the evaluation of a value until later. For example, maybe we will
need to generate a very long list and find its sum, but we do not want to do
it unless it is absolutely necessary.
lazySum : Lazy Int
lazySum =
lazy (\() -> sum <| List.range 1 1000000 )
Now we only pay for `lazySum` if we actually need it.
-}
lazy : (() -> a) -> Lazy a
lazy thunk =
Lazy thunk
{-| Force the evaluation of a lazy value. This means we only pay for the
computation when we need it. Here is a rather contrived example.
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
sums : (Int, Int, Int)
sums =
(force lazySum, force lazySum, force lazySum)
-}
force : Lazy a -> a
force piece =
case piece of
Evaluated a ->
a
Lazy thunk ->
thunk ()
{-| Evaluate the lazy value if it has not already been evaluated. If it has,
do nothing.
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
sums : (Int, Int, Int)
sums =
let
evaledSum =
evaluate lazySum
in
(force evaledSum, force evaledSum, force evaledSum)
This is mainly useful for cases where you may want to store a lazy value as a
lazy value and pass it around. For example, in a list. Where possible, it is better to use
`force` and simply store the computed value seperately.
-}
evaluate : Lazy a -> Lazy a
evaluate piece =
case piece of
Evaluated a ->
Evaluated a
Lazy thunk ->
thunk ()
|> Evaluated
-- COMPOSING LAZINESS
{-| Lazily apply a function to a lazy value.
lazySum : Lazy Int
lazySum =
map List.sum (lazy (\() -> <| List.range 1 1000000)
The resulting lazy value will create a big list and sum it up when it is
finally forced.
-}
map : (a -> b) -> Lazy a -> Lazy b
map f a =
lazy (\() -> f (force a))
{-| Lazily apply a function to two lazy values.
lazySum : Lazy Int
lazySum =
lazy (\() -> List.sum <| List.range 1 1000000)
lazySumPair : Lazy (Int, Int)
lazySumPair =
map2 (,) lazySum lazySum
-}
map2 : (a -> b -> result) -> Lazy a -> Lazy b -> Lazy result
map2 f a b =
lazy (\() -> f (force a) (force b))
{-| -}
map3 : (a -> b -> c -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy result
map3 f a b c =
lazy (\() -> f (force a) (force b) (force c))
{-| -}
map4 : (a -> b -> c -> d -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy d -> Lazy result
map4 f a b c d =
lazy (\() -> f (force a) (force b) (force c) (force d))
{-| -}
map5 : (a -> b -> c -> d -> e -> result) -> Lazy a -> Lazy b -> Lazy c -> Lazy d -> Lazy e -> Lazy result
map5 f a b c d e =
lazy (\() -> f (force a) (force b) (force c) (force d) (force e))
{-| Lazily apply a lazy function to a lazy value. This is pretty rare on its
own, but it lets you map as high as you want.
map3 f a b == f `map` a `apply` b `apply` c
It is not the most beautiful, but it is equivalent and will let you create
`map9` quite easily if you really need it.
-}
apply : Lazy (a -> b) -> Lazy a -> Lazy b
apply f x =
lazy (\() -> (force f) (force x))
{-| Lazily chain together lazy computations, for when you have a series of
steps that all need to be performed lazily. This can be nice when you need to
pattern match on a value, for example, when appending lazy lists:
type List a = Empty | Node a (Lazy (List a))
cons : a -> Lazy (List a) -> Lazy (List a)
cons first rest =
Lazy.map (Node first) rest
append : Lazy (List a) -> Lazy (List a) -> Lazy (List a)
append lazyList1 lazyList2 =
let
appendHelp list1 =
case list1 of
Empty ->
lazyList2
Node first rest ->
cons first (append rest list2))
in
lazyList1
|> Lazy.andThen appendHelp
By using `andThen` we ensure that neither `lazyList1` or `lazyList2` are forced
before they are needed. So as written, the `append` function delays the pattern
matching until later.
-}
andThen : (a -> Lazy b) -> Lazy a -> Lazy b
andThen callback a =
lazy (\() -> force (callback (force a)))
```