The Lazy Monad

class hymn.types.lazy.Lazy(value)

Bases: hymn.types.monad.Monad

the lazy monad

lazy computation as monad

bind(f)

the bind operator of Lazy

evaluate()

evaluate the lazy monad

evaluated

return True if this computation is evaluated

classmethod unit(value)

the unit of lazy monad

hymn.types.lazy.evaluate(self)

evaluate the lazy monad

hymn.types.lazy.force(m)

force the deferred computation m if it is a Lazy, act as function identity otherwise, return the result

hymn.types.lazy.is_lazy(v)

return True if v is a Lazy

hymn.types.lazy.lazy_m

alias of Lazy

hymn.types.lazy.unit()

alias of Lazy.unit()

hymn.types.lazy.evaluate()

alias of Lazy.evaluate()

Hy Specific API

lazy-m

alias of Lazy

Macro

lazy [&rest exprs]

create a Lazy from expressions, the expressions will not be evaluated until being forced by force() or evaluate()

Function

lazy?

alias of is_lazy()

Examples

Do Notation

=> (require hymn.dsl)
=> (require hymn.types.lazy)
=> (def two (do-monad [x (lazy (print "evaluate two") 2)] x))
=> two
Lazy(_)
=> (.evaluate two)
evaluate two
2

Operations

Use macro lazy() to create deferred computation from expressions, the computation will not be evaluated until asked explicitly

=> (require hymn.dsl)
=> (require hymn.types.lazy)
=> (def answer (lazy (print "the answer is ...") 42))
=> answer
Lazy(_)
=> (.evaluate answer)
the answer is ...
42
=> (.evaluate answer)
42

Deferred computation can also be created with expressions wrapped in a function

=> (import [hymn.types.lazy [lazy-m]])
=> (def a (lazy-m (fn [] (print "^o^") 42)))
=> (.evaluate a)
^o^
42

Use evaluate() to evaluate the computation, the result will be cached

=> (require hymn.types.lazy)
=> (def who (lazy (input "enter your name? ")))
=> who
Lazy(_)
=> (.evaluate who)
enter your name? Marvin
'Marvin'
=> who
Lazy('Marvin')
=> (import [hymn.operations [lift]])
=> (def m+ (lift +))
=> (def x (lazy (print "get x") 2))
=> x
Lazy(_)
=> (def x3 (m+ x x x))
=> x3
Lazy(_)
=> (.evaluate x3)
get x
6
=> x
Lazy(2)
=> x3
Lazy(6)

Use force() to evaluate Lazy as well as other values

=> (require hymn.types.lazy)
=> (import [hymn.types.lazy [force]])
=> (force (lazy (print "yes") 1))
yes
1
=> (force 1)
1
=> (def a (lazy (print "Stat!") (+ 1 2 3)))
=> a
Lazy(_)
=> (force a)
Stat!
6
=> a
Lazy(6)

lazy?() returns True if the object is a Lazy value

=> (import [hymn.types.lazy [lazy-m lazy?]])
=> (lazy? 1)
False
=> (lazy? (lazy-m.unit 1))
True