Class: Propr::Random
- Extended by:
- Fr::Monad
- Defined in:
- lib/propr/random.rb
Class Method Summary collapse
- .bind(f, &g) ⇒ Object
- .eval(computation, scale = BigDecimal(1), retries = 0) ⇒ Object
-
.guard(*conditions) ⇒ Object
TODO: Make Random an instance of Functor and use Functor.guard?.
-
.rand(limit = nil) ⇒ Object
Generate psuedo-random number normally distributed between 0 <= x < 1.
-
.run(computation, scale = BigDecimal(1)) ⇒ Object
Evaluators.
-
.scale(number, range, zero) ⇒ Object
When given two arguments, scales a numeric value around a given origin ‘zero`, using the current scale factor (0..1).
-
.unit(value) ⇒ Object
Combinators.
Class Method Details
.bind(f, &g) ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'lib/propr/random.rb', line 40 def bind(f, &g) lambda do |scale| value, scale, success = f.call(scale) success ? g.call(value).call(scale) : [value, scale, success] end end |
.eval(computation, scale = BigDecimal(1), retries = 0) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/propr/random.rb', line 16 def eval(computation, scale = BigDecimal(1), retries = 0) skipped = 0 scale = bound(scale) while true value, _, success = computation.call(scale) if success return value elsif (skipped += 1) > retries raise NoMoreTries, retries end end end |
.guard(*conditions) ⇒ Object
TODO: Make Random an instance of Functor and use Functor.guard?
54 55 56 57 58 |
# File 'lib/propr/random.rb', line 54 def guard(*conditions) lambda do |scale| [nil, scale, conditions.all?] end end |
.rand(limit = nil) ⇒ Object
Generate psuedo-random number normally distributed between 0 <= x < 1. This distribution is not weighted using ‘scale`.
83 84 85 86 87 88 89 90 91 |
# File 'lib/propr/random.rb', line 83 def rand(limit = nil) if not limit.nil? and limit <= 0 raise InvalidArgument, "limit <= 0" end lambda do |scale| [Kernel.rand(limit), scale, true] end end |
.run(computation, scale = BigDecimal(1)) ⇒ Object
Evaluators
12 13 14 |
# File 'lib/propr/random.rb', line 12 def run(computation, scale = BigDecimal(1)) computation.call(bound scale) end |
.scale(number, range, zero) ⇒ Object
When given two arguments, scales a numeric value around a given origin ‘zero`, using the current scale factor (0..1).
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/propr/random.rb', line 63 def scale(number, range, zero) if range.zero? # No scaling lambda do |scale| [number, scale, true] end else # Shrink range exponentially, and -1 + scale reduces the # rng_ to 0 when scale = 0, but rng_ = range when scale = 1. lambda do |scale| rng_ = (range ** scale) - 1 + scale pct = (number - zero) / range [zero + rng_ * pct, scale, true] end end end |
.unit(value) ⇒ Object
Combinators
34 35 36 37 38 |
# File 'lib/propr/random.rb', line 34 def unit(value) lambda do |scale| [value, scale, true] end end |