2013-12-09 21:16:04 +00:00
|
|
|
module Lazy ( force, lazy, map, apply, bind
|
2013-12-09 06:01:32 +00:00
|
|
|
) where
|
2013-12-07 20:22:57 +00:00
|
|
|
|
2013-12-09 06:01:32 +00:00
|
|
|
{-| Library for efficient Lazy evaluation.
|
2013-12-07 20:22:57 +00:00
|
|
|
|
2013-12-09 21:19:41 +00:00
|
|
|
# Delay
|
|
|
|
@docs lazy
|
|
|
|
|
|
|
|
# Evaluate
|
|
|
|
@docs force
|
|
|
|
|
|
|
|
# Transform
|
|
|
|
@docs map, apply, bind
|
2013-12-07 20:22:57 +00:00
|
|
|
-}
|
|
|
|
|
2013-12-09 06:39:11 +00:00
|
|
|
import Basics ((<|), (.))
|
2013-12-07 20:22:57 +00:00
|
|
|
import Native.Lazy
|
|
|
|
|
2013-12-09 21:16:04 +00:00
|
|
|
data Lazy a = L { force : () -> a }
|
2013-12-07 20:22:57 +00:00
|
|
|
|
2013-12-14 01:05:33 +00:00
|
|
|
{-| Delay a computation. This function memoizes results, so
|
|
|
|
it guarantees that the computation will be evaluated at most once.
|
|
|
|
-}
|
2013-12-09 21:16:04 +00:00
|
|
|
lazy : (() -> a) -> Lazy a
|
|
|
|
lazy t = L { force = (Native.Lazy.lazy t) }
|
2013-12-07 20:22:57 +00:00
|
|
|
|
2013-12-14 01:05:33 +00:00
|
|
|
{-| Evaluate a lazy value. It saves the result so the second time
|
|
|
|
you call `force` it does not run the computation again. -}
|
2013-12-09 21:16:04 +00:00
|
|
|
force : Lazy a -> a
|
|
|
|
force (L r) = r.force ()
|
2013-12-07 20:30:51 +00:00
|
|
|
|
2013-12-14 01:05:33 +00:00
|
|
|
{-| Lazily apply a function to a lazy value. The computation
|
|
|
|
will be delayed until you force the resulting value.
|
|
|
|
-}
|
2013-12-09 06:39:11 +00:00
|
|
|
map : (a -> b) -> Lazy a -> Lazy b
|
2013-12-09 21:16:04 +00:00
|
|
|
map f t = lazy <| \() ->
|
|
|
|
f . force <| t
|
2013-12-09 06:39:11 +00:00
|
|
|
|
2013-12-14 01:05:33 +00:00
|
|
|
{-| Lazily apply a lazy function to a lazy value. This can
|
|
|
|
be used to lazily apply a function to many arguments:
|
|
|
|
|
|
|
|
```haskell
|
|
|
|
f `map` a `apply` b `apply` c
|
|
|
|
```
|
|
|
|
-}
|
2013-12-09 06:39:11 +00:00
|
|
|
apply : Lazy (a -> b) -> Lazy a -> Lazy b
|
2013-12-09 21:16:04 +00:00
|
|
|
apply f x = lazy <| \() ->
|
|
|
|
(force f) (force x)
|
2013-12-09 06:39:11 +00:00
|
|
|
|
2013-12-14 01:05:33 +00:00
|
|
|
{-| Lazily chain together lazy computations. -}
|
2013-12-09 06:39:11 +00:00
|
|
|
bind : Lazy a -> (a -> Lazy b) -> Lazy b
|
2013-12-09 21:16:04 +00:00
|
|
|
bind x k = lazy <| \() ->
|
|
|
|
force . k . force <| x
|