module Mon

Contract for the Mon::Future monad, for use with the Contracts gem For example: <tt>Contract C::Future => C::Future def futureSquare(l)

l.bind { |i| i * i }

end</tt> will work only for (eg) futureSquare(Mon::Future.eventually { wait_for_number_from_thread }). If passed anything (or returning anything) other than a Mon::Future, a ContractViolation will be thrown. Note: since Ruby is dynamically typed, we can't ensure that the eventual value will be of the correct type. So: futureSquare(Mon::Future.eventually { wait_for_string_from_thread }) is likely to succeed (if the thread is still in-flight), and fail when the thread returns. Completed Futures don't have this issue.

Contract for the Mon::Lazy monad, for use with the Contracts gem For example: <tt>Contract C::Lazy => C::Lazy def lazySquare(l)

l.bind { |i| i * i }

end</tt> will work only for (eg) lazySquare(Mon::Lazy.eventually { perform_painful_op_only_if_necessary() }). If passed anything (or returning anything) other than a Mon::Lazy, a ContractViolation will be thrown. Note: since Ruby is dynamically typed, we can't ensure that the eventual value will be of the correct type. So: lazySquare(Mon::Lazy.eventually { op_returning_string }) is likely to succeed, and fail when the operation is actually executed. Finalized Lazy monads don't have this issue.

Contract for the Mon::List monad, for use with the Contracts gem For example: <tt>Contract C::List => C::List def listSquare(l)

l.bind { |i| i * i }

end</tt> will work only for listSquare(Mon::List[1, 2, 3, 4]). If passed anything (or returning anything) other than a Mon::List, a ContractViolation will be thrown.

Contract for the Mon::React monad, for use with the Contracts gem For example: <tt>Contract C::React => C::React def reactSquare(l)

l.bind { |i| i * i }

end</tt> will work only for (eg) reactSquare(Mon::React). If passed anything (or returning anything) other than a Mon::React, a ContractViolation will be thrown.

Contract for the Mon::Try monad, for use with the Contracts gem For example: <tt>Contract C::Try => C::Try def trySquare(l)

l.bind { |i| i * i }

end</tt> will work only for (eg) trySquare(Mon::Try.to { get_num_from_remote_service() }). If passed anything (or returning anything) other than a Mon::Try, a ContractViolation will be thrown.

Base class for Mon monads. Do not instantiate.

Future wraps an asynchronous process and acts as a placeholder.

A simple example: <tt>f = Future.eventually { call_remote_web_service } data = f.bind { |response| response.getContent } while data.pending?

puts "Still waiting..."
sleep 1

end puts “Got a response: #{ data.unwrap }” </tt>

Rather than explicitly waiting, you can always block on an answer: data = f.bind { |r| r.getContent } puts "Got a response: #{ data.finalize.unwrap }"

Lazy wraps computations which will only be performed on-demand.

A simple example: l = Lazy.eventually(n) { perform_some_slow_operation(n) } data = f.bind { |result| some_even_more_costly_operation(result) } # At this point, no real computation has taken place puts "Here's the result: #{ data.unwrap } # ouch!

Why would you ever want to do this? Here's an example: factNums = (0..100000).map { |i| Lazy[i] }.map { |m| m.bind { |i| i.factorial } } # We now have a list of 100000 'potential' factorial numbers, but # we've done this very quickly: we haven't actually done any math yet. fiveThousandFact = factNums[5000].unwrap # We've performed exactly one factorial operation! And yet we can pass around # and use factNums as if it really was a list of factorials. Neat!

The List monad wraps lists. Gasp!

A simple example: l = List[1, 2, 3] list9 = l.bind { |i| i * 9 } # ==> List[9, 18, 27] longList = l.bind { |i| [i, i * 2] } # ==> List[1, 2, 2, 4, 3, 6]

Simple and straightforward.

The Maybe monad wraps a possible value. It allows chaining of operations on a potentially-null value.

A simple example: m = Maybe[callSomeIntOrNilFunction()] v = (m * 3 + 2).abs # Depending whether the original method call returned a number or nil, # could be either None or Some[N].

The React monad wraps a changeable value, and catches changes to that value.

A simple example: r = React[5] d = r * r # Currently r = Reactron[5], d = Reactor[25] r << 25 # Now r = Reactron[25], d = Reactor[625] dd = d * 2 # d = Reactor[625], dd = Reactor[1250]

More or less, this is a Listener pattern. Reactrons are listenable, Reactors are listeners.

Constants

C

Namespace aliases

M