The Lazy Monad

class hymn.types.lazy.Lazy

the lazy monad

lazy computation as monad

bind(self, f)

the bind operator of Lazy

classmethod unit(cls, value)

the unit of lazy monad

evaluate(self)

evaluate the lazy monad

property evaluated

return True if this computation is evaluated

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(m)

return True if v is a Lazy

Hy Specific API

lazy-m

alias of Lazy

lazy?

alias of is_lazy()

Macro

hymn.types.lazy.lazy[]()

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

Examples

Do Notation

=> (require hymn.macros [do-monad-return])
=> (require hymn.types.lazy [lazy])
=> (setv two (do-monad-return [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.types.lazy [lazy])
=> (setv 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])
=> (setv 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 [lazy])
=> (setv who (lazy (input "enter your name? ")))
=> who
Lazy(_)
=> (.evaluate who)
enter your name? Marvin
"Marvin"
=> who
Lazy('Marvin')
=> (import hymn.operations [lift])
=> (import hy.pyops [+])
=> (setv m+ (lift +))
=> (setv x (lazy (print "get x") 2))
=> x
Lazy(_)
=> (setv 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

=> (import hymn.types.lazy [force])
=> (require hymn.types.lazy [lazy])
=> (force (lazy (print "yes") 1))
yes
1
=> (force 1)
1
=> (setv 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?])
=> (require hymn.types.lazy [lazy])
=> (lazy? 1)
False
=> (lazy? (lazy 1))
True