The Writer Monad

class hymn.types.writer.Writer

the writer monad

computation which accumulate output along with result

bind(self, f)

the bind operation of Writer

classmethod unit(cls, value)

the unit of writer monad

execute()

extract the output of writer

run()

unwrap the writer computation

hymn.types.writer.writer_with_type(t)

create a writer for type t

Predefined Writers

class hymn.types.writer.ComplexWriter
class hymn.types.writer.DecimalWriter
class hymn.types.writer.FloatWriter
class hymn.types.writer.FractionWriter
class hymn.types.writer.ListWriter
class hymn.types.writer.IntWriter
class hymn.types.writer.StringWriter
class hymn.types.writer.TupleWriter

Hy Specific API

writer-m

alias of Writer

writer-with-type

alias of writer_with_type()

writer-with-type-of

alias of writer_with_type_of()

Reader Macro

+ [w]

create a writer that logs w

Writers

complex-writer-m

alias of ComplexWriter

decimal-writer-m

alias of DecimalWriter

float-writer-m

alias of FloatWriter

fraction-writer-m

alias of FractionWriter

list-writer-m

alias of ListWriter

int-writer-m

alias of IntWriter

string-writer-m

alias of StringWriter

tuple-writer-m

alias of TupleWriter

Examples

Do Notation

=> (import hymn.types.writer [tell])
=> (require hymn.macros [do-monad-return])
=> (do-monad-return [_ (tell 1) _ (tell 2)] None)
IntWriter((None, 3))
=> (do-monad-return [_ (tell "hello ") _ (tell "world!")] None)
StrWriter((None, 'hello world!'))

Operations

writer() creates a Writer

=> (import hymn.types.writer [writer])
=> (writer None 1)
IntWriter((None, 1))

tell() adds message into accumulated values of writer

=> (import hymn.types.writer [tell writer])
=> (.run (tell 1))
#(None 1)
(None, 1)
=> (.run (>> (writer 1 1) tell))
#(None 2)

tell() and writer() are smart enough to create writer of appropriate type

=> (import hymn.types.writer [tell writer])
=> (writer None 98j)
ComplexWriter((None, 98j))
=> (import decimal [Decimal])
=> (writer None (Decimal "7.31"))
DecimalWriter((None, Decimal('7.31')))
=> (writer None 1.0)
FloatWriter((None, 1.0))
=> (writer None [85 70 92])
ListWriter((None, [85, 70, 92]))
=> (writer None 1)
IntWriter((None, 1))
=> (writer None "a")
StrWriter((None, 'a'))
=> (writer None #(1151130 1151330))
TupleWriter((None, (1151130, 1151330)))
=> (tell 98j)
ComplexWriter((None, 98j))
=> (tell (Decimal "7.31"))
DecimalWriter((None, Decimal('7.31')))
=> (tell 1.0)
FloatWriter((None, 1.0))
=> (tell [85 70 92])
ListWriter((None, [85, 70, 92]))
=> (tell 1)
IntWriter((None, 1))
=> (tell "a")
StrWriter((None, 'a'))
=> (tell #(1151130 1151330))
TupleWriter((None, (1151130, 1151330)))

Use listen() to get the value of the writer

=> (import hymn.types.writer [listen writer])
=> (listen (writer "value" 42))
IntWriter((('value', 42), 42))

Use censor() to apply function to the output

=> (import hymn.types.writer [censor tell])
=> (require hymn.macros [do-monad-return])
=> (setv logs (do-monad-return [_ (tell [1]) _ (tell [2]) _ (tell [3])] None))
=> (.execute logs)
[1 2 3]
=> (.execute (censor sum logs))
6

Reader Macro

=> (require hymn.types.writer :readers [+])
=> ;; reader macro + works like tell
=> #+ 1
IntWriter((None, 1))
=> (.execute #+ 1)
1
=> (require hymn.macros [do-monad-return])
=> (do-monad-return [_ #+ 1 _ #+ 2 _ #+ 4] 42)
IntWriter((42, 7))