GTof-ruby-do-notation 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ lib/do_notation/monad.rb
2
+ lib/do_notation/monad_plus.rb
3
+ lib/do_notation/monads/array.rb
4
+ lib/do_notation/monads/maybe.rb
5
+ lib/do_notation/monads/simulations.rb
6
+ lib/do_notation/rewriter.rb
7
+ lib/do_notation.rb
8
+ README.markdown
9
+ test/array.rb
10
+ test/maybe.rb
11
+ test/monad_plus.rb
12
+ test/simulations.rb
13
+ test/spec_helper.rb
14
+ test/specs.rb
15
+ Manifest
@@ -0,0 +1,34 @@
1
+ Haskell-style monad do-notation for Ruby
2
+ ========================================
3
+
4
+ Example:
5
+
6
+ class Array
7
+ include Monad
8
+
9
+ def self.unit x
10
+ [x]
11
+ end
12
+
13
+ def bind &f
14
+ map(&f).inject([]){ |a,b| a+b }
15
+ end
16
+ end
17
+
18
+ Array.run do
19
+ x <- ["first", "second"]
20
+ y <- ["once", "twice"]
21
+
22
+ unit("#{x} cousin #{y} removed")
23
+ end
24
+
25
+ The above code returns the array:
26
+
27
+ ["first cousin once removed",
28
+ "first cousin twice removed",
29
+ "second cousin once removed",
30
+ "second cousin twice removed"]
31
+
32
+ For more examples, see the test suite.
33
+
34
+ By Aanand Prasad (aanand.prasad@gmail.com)
@@ -0,0 +1,27 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ spec_list = FileList['test/*.rb']
4
+
5
+ task :default => :test
6
+
7
+ desc "Run all specs"
8
+ Spec::Rake::SpecTask.new('spec') do |t|
9
+ t.spec_files = spec_list
10
+ end
11
+
12
+ desc "Run all specs with RCov"
13
+ Spec::Rake::SpecTask.new('rcov') do |t|
14
+ t.spec_files = spec_list
15
+ t.rcov = true
16
+ end
17
+
18
+ require 'echoe'
19
+
20
+ Echoe.new('ruby-do-notation') do |p|
21
+ p.author = 'Aanand Prasad'
22
+ p.summary = 'Haskell-style monad do-notation for Ruby'
23
+ p.email = 'aanand.prasad@gmail.com'
24
+ p.url = 'http://github.com/aanand/ruby-do-notation/tree/master'
25
+ p.version = '0.2'
26
+ p.dependencies = ['ParseTree', 'ruby2ruby']
27
+ end
@@ -0,0 +1,9 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'parse_tree'
5
+ require 'sexp_processor'
6
+ require 'ruby2ruby'
7
+
8
+ require 'do_notation/rewriter'
9
+ require 'do_notation/monad'
@@ -0,0 +1,101 @@
1
+ # Modeled after Andrzej Filinski's article "Representing
2
+ # Monads" at POPL'94, and a Scheme implementation of it.
3
+ # http://citeseer.ist.psu.edu/filinski94representing.html
4
+
5
+ module ShiftReset
6
+ @@metacont = lambda { |x|
7
+ raise RuntimeError, "You forgot the top-level reset..."
8
+ }
9
+
10
+ def reset(&block)
11
+ mc = @@metacont
12
+ callcc { |k|
13
+ @@metacont = lambda { |v|
14
+ @@metacont = mc
15
+ k.call v
16
+ }
17
+ x = block.call
18
+ @@metacont.call x
19
+ }
20
+ end
21
+
22
+ def shift(&block)
23
+ callcc { |k|
24
+ @@metacont.call block.call(lambda { |*v| reset { k.call *v } })
25
+ }
26
+ end
27
+ end
28
+
29
+ include ShiftReset
30
+
31
+ module Monad
32
+ module ClassMethods
33
+ def run &block
34
+ eval(ruby_for(block), block).call
35
+ end
36
+
37
+ def ruby_for block
38
+ @cached_ruby ||= {}
39
+ @cached_ruby[block.to_s] ||= "#{self.name}.instance_eval { #{Ruby2Ruby.new.process(Rewriter.new.process(block.to_method.to_sexp)[2])} }"
40
+ end
41
+
42
+ def sequence l
43
+ if l.empty?
44
+ unit([])
45
+ else
46
+ run do
47
+ x <- l[0]
48
+ q <- sequence(l[1..-1])
49
+ unit([x] + q)
50
+ end
51
+ end
52
+ end
53
+
54
+ def foldM(i,l, &f)
55
+ if l.empty?
56
+ unit(i)
57
+ else
58
+ run do
59
+ x <- f.call(i,l[0])
60
+ foldM(x,l[1..-1]) { |a,b| f.call(a,b) }
61
+ end
62
+ end
63
+ end
64
+
65
+ def fmap f
66
+ lambda { |m| m.bind { |y| unit(f.call(y)) } }
67
+ end
68
+
69
+ def reify &t
70
+ reset { unit( t.call() ) }
71
+ end
72
+
73
+ def reflect m
74
+ shift { |k| m.bind { |v| k.call(v) } }
75
+ end
76
+ end
77
+
78
+ def self.included m
79
+ m.extend ClassMethods
80
+ end
81
+
82
+ def bind_const &block
83
+ bind { |_| block.call() }
84
+ end
85
+
86
+ def >> n
87
+ bind_const { n }
88
+ end
89
+
90
+ def joinM
91
+ bind { |n| n }
92
+ end
93
+
94
+ # I don't know why this reflect doesn't work
95
+ # the class method seems to be the same and work
96
+ # the evaluation moment of the shift in a class method
97
+ # and in a method may be different
98
+ def reflect_that_doesnt_work
99
+ shift { |k| bind { |v| k.call(v) } }
100
+ end
101
+ end
@@ -0,0 +1,9 @@
1
+ module MonadPlus
2
+ def guard p
3
+ if p
4
+ unit(mzero)
5
+ else
6
+ mzero
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ require 'do_notation/monad_plus'
2
+
3
+ class Array
4
+ include Monad
5
+
6
+ def self.unit x
7
+ [x]
8
+ end
9
+
10
+ def bind &f
11
+ map(&f).inject([]){ |a,b| a+b }
12
+ end
13
+
14
+ extend MonadPlus
15
+
16
+ def self.mzero
17
+ []
18
+ end
19
+
20
+ alias_method :mplus, :+
21
+ end
@@ -0,0 +1,31 @@
1
+ require 'do_notation/monad_plus'
2
+
3
+ class Maybe < Struct.new(:value)
4
+ include Monad
5
+
6
+ def self.unit value
7
+ self.new(value)
8
+ end
9
+
10
+ def bind &f
11
+ if value.nil?
12
+ self
13
+ else
14
+ f.call(value)
15
+ end
16
+ end
17
+
18
+ extend MonadPlus
19
+
20
+ def self.mzero
21
+ unit(nil)
22
+ end
23
+
24
+ def mplus m
25
+ if value.nil?
26
+ m
27
+ else
28
+ self
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,117 @@
1
+ # converted from Mauricio Fernandez's "Warm fuzzy things for random simulations":
2
+ # http://eigenclass.org/hiki/warm-fuzzy-things-for-random-simulations
3
+ # http://eigenclass.org/hiki.rb?c=plugin;plugin=attach_download;p=warm-fuzzy-things-for-random-simulations;file_name=fuzzy-warm-simulations.rb
4
+
5
+ module PRNG
6
+ def next_state(s); (69069 * s + 5) % (2**32) end
7
+ end
8
+
9
+ class Simulation
10
+ extend PRNG
11
+ include Monad
12
+
13
+ attr_reader :f
14
+
15
+ def initialize(&b)
16
+ @f = b
17
+ end
18
+
19
+ def self.unit(x)
20
+ new { |s| [x, s] }
21
+ end
22
+
23
+ def self.rand(n)
24
+ self.new do |s|
25
+ [s.abs % n, next_state(s)]
26
+ end
27
+ end
28
+
29
+ def bind(&b)
30
+ self.class.new do |s|
31
+ x, s = @f.call(s)
32
+ b.call(x).f.call(s)
33
+ end
34
+ end
35
+
36
+ def play(s = 12345)
37
+ @f.call(s).first
38
+ end
39
+ end
40
+
41
+ class Distribution
42
+ extend PRNG
43
+ include Monad
44
+
45
+ attr_reader :a
46
+
47
+ def initialize(a)
48
+ @a = a
49
+ end
50
+
51
+ def self.wrap(a)
52
+ new(a)
53
+ end
54
+
55
+ def self.unit(x)
56
+ wrap [[x, 1.0]]
57
+ end
58
+
59
+ def self.rand(n)
60
+ p = 1.0 / n
61
+ new((0...n).map{|i| [i, p]})
62
+ end
63
+
64
+ def bind(&b)
65
+ if @a.empty?
66
+ self.class.wrap([])
67
+ else
68
+ x, p = @a[0]
69
+ self.class.wrap(mulp(p, b.call(x)) + self.class.new(@a[1..-1]).bind(&b).a)
70
+ end
71
+ end
72
+
73
+ def play
74
+ h = Hash.new{|h, k| h[k] = 0.0}
75
+ @a.each{|x, p| h[x] += p}
76
+ h.to_a.sort_by{|x,| x}
77
+ end
78
+
79
+ private
80
+ def mulp(p, l)
81
+ l.a.map{|x, p1| [x, p * p1]}
82
+ end
83
+ end
84
+
85
+ class Expectation
86
+ extend PRNG
87
+ include Monad
88
+
89
+ attr_reader :f
90
+
91
+ def initialize(&b)
92
+ @f = b
93
+ end
94
+
95
+ def self.wrap(&proc)
96
+ new(&proc)
97
+ end
98
+
99
+ def self.unit(x)
100
+ wrap{ |f| f.call(x) }
101
+ end
102
+
103
+ def self.rand(n)
104
+ wrap do |k|
105
+ sum = (0..n-1).map{|x| k.call(x)}.inject{|s,x| s+x}
106
+ 1.0 * sum / n
107
+ end
108
+ end
109
+
110
+ def bind(&b)
111
+ self.class.wrap{|k| @f.call(lambda{|x| b.call(x).f.call(k)}) }
112
+ end
113
+
114
+ def play(x)
115
+ @f.call(lambda{|x1| x1 == x ? 1.0 : 0.0})
116
+ end
117
+ end
@@ -0,0 +1,63 @@
1
+ class Rewriter < SexpProcessor
2
+ def process_bmethod exp
3
+ type = exp.shift
4
+
5
+ exp.shift # throw away arguments
6
+
7
+ body = process(exp.shift)
8
+
9
+ if body[0] == :block
10
+ body.shift
11
+ else
12
+ body = s([*body])
13
+ end
14
+
15
+ s(:iter, s(:fcall, :proc), nil, *rewrite_assignments(body))
16
+ end
17
+
18
+ def rewrite_assignments exp
19
+ return [] if exp.empty?
20
+
21
+ head = exp.shift
22
+
23
+ if head.first == :call and head[1].first == :vcall and head[2] == :< and head[3].first == :array and head[3][1].last == :-@
24
+ var_name = head[1][1]
25
+ expression = head[3][1][1]
26
+
27
+ body = rewrite_assignments(exp)
28
+
29
+ if body.first.is_a? Symbol
30
+ body = [s(*body)]
31
+ end
32
+
33
+ [s(:iter,
34
+ s(:call, process(expression), :bind),
35
+ s(:dasgn_curr, var_name),
36
+ *body)]
37
+ elsif exp.empty?
38
+ [process(head)]
39
+ else
40
+ [s(:iter, s(:call, process(head) , :bind_const), nil ,
41
+ *rewrite_assignments(exp)) ]
42
+ end
43
+ end
44
+
45
+ def self.pp(obj, indent='')
46
+ return obj.inspect unless obj.is_a? Array
47
+ return '()' if obj.empty?
48
+
49
+ str = '(' + pp(obj.first, indent + ' ')
50
+
51
+ if obj.length > 1
52
+ str << ' '
53
+
54
+ next_indent = indent + (' ' * str.length)
55
+
56
+ str << obj[1..-1].map{ |o| pp(o, next_indent) }.join("\n#{next_indent}")
57
+ end
58
+
59
+ str << ')'
60
+
61
+ str
62
+ end
63
+ end
@@ -0,0 +1,38 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{ruby-do-notation}
3
+ s.version = "0.2"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Aanand Prasad"]
7
+ s.date = %q{2009-02-03}
8
+ s.description = %q{Haskell-style monad do-notation for Ruby}
9
+ s.email = %q{aanand.prasad@gmail.com}
10
+ s.extra_rdoc_files = ["lib/do_notation/monad.rb", "lib/do_notation/monad_plus.rb", "lib/do_notation/monads/array.rb", "lib/do_notation/monads/maybe.rb", "lib/do_notation/monads/simulations.rb", "lib/do_notation/rewriter.rb", "lib/do_notation.rb", "README.markdown"]
11
+ s.files = ["lib/do_notation/monad.rb", "lib/do_notation/monad_plus.rb", "lib/do_notation/monads/array.rb", "lib/do_notation/monads/maybe.rb", "lib/do_notation/monads/simulations.rb", "lib/do_notation/rewriter.rb", "lib/do_notation.rb", "README.markdown", "test/array.rb", "test/maybe.rb", "test/monad_plus.rb", "test/simulations.rb", "test/spec_helper.rb", "test/specs.rb", "Manifest", "ruby-do-notation.gemspec", "Rakefile"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/aanand/ruby-do-notation/tree/master}
14
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ruby-do-notation", "--main", "README.markdown"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{ruby-do-notation}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{Haskell-style monad do-notation for Ruby}
19
+
20
+ if s.respond_to? :specification_version then
21
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
+ s.specification_version = 2
23
+
24
+ if current_version >= 3 then
25
+ s.add_runtime_dependency(%q<ParseTree>, [">= 0"])
26
+ s.add_runtime_dependency(%q<ruby2ruby>, [">= 0"])
27
+ s.add_development_dependency(%q<echoe>, [">= 0"])
28
+ else
29
+ s.add_dependency(%q<ParseTree>, [">= 0"])
30
+ s.add_dependency(%q<ruby2ruby>, [">= 0"])
31
+ s.add_dependency(%q<echoe>, [">= 0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<ParseTree>, [">= 0"])
35
+ s.add_dependency(%q<ruby2ruby>, [">= 0"])
36
+ s.add_dependency(%q<echoe>, [">= 0"])
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'do_notation/monads/array'
3
+
4
+ describe "Array:" do
5
+ specify "all results are calculated and concatenated" do
6
+ array = Array.run do
7
+ x <- ["first", "second"]
8
+ y <- ["once", "twice"]
9
+
10
+ unit("#{x} cousin #{y} removed")
11
+ end
12
+
13
+ array.should == ["first cousin once removed",
14
+ "first cousin twice removed",
15
+ "second cousin once removed",
16
+ "second cousin twice removed"]
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'do_notation/monads/maybe'
3
+
4
+ describe "Maybe:" do
5
+ specify "one or more nils results in nil" do
6
+ maybe = Maybe.run do
7
+ x <- unit(1)
8
+ y <- unit(nil)
9
+
10
+ unit(x+y)
11
+ end
12
+
13
+ maybe.value.should == nil
14
+ end
15
+
16
+ specify "all non-nil results in complete calculation" do
17
+ maybe = Maybe.run do
18
+ x <- unit(1)
19
+ y <- unit(2)
20
+
21
+ unit(x+y)
22
+ end
23
+
24
+ maybe.value.should == 3
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'do_notation/monads/array'
3
+ require 'do_notation/monads/maybe'
4
+
5
+ describe "MonadPlus:" do
6
+ specify "mzero >>= f = mzero" do
7
+ Array.mzero.bind{ |x| unit(x+1) }.should == Array.mzero
8
+ Maybe.mzero.bind{ |x| unit(x+1) }.should == Maybe.mzero
9
+ end
10
+
11
+ specify "v >> mzero = mzero" do
12
+ ([1,2,3] >> Array.mzero).should == Array.mzero
13
+ (Maybe.unit(1) >> Maybe.mzero).should == Maybe.mzero
14
+ end
15
+
16
+ specify "mzero `mplus` m = m" do
17
+ Array.mzero.mplus([1,2,3]).should == [1,2,3]
18
+ Maybe.mzero.mplus(Maybe.unit(1)).should == Maybe.unit(1)
19
+ end
20
+
21
+ specify "m `mplus` mzero = m" do
22
+ [1,2,3].mplus(Array.mzero).should == [1,2,3]
23
+ Maybe.unit(1).mplus(Maybe.mzero).should == Maybe.unit(1)
24
+ end
25
+
26
+ specify "guard() prunes the execution tree" do
27
+ array = Array.run do
28
+ x <- [0,1,2,3]
29
+ y <- [0,1,2,3]
30
+ guard(x + y == 3)
31
+
32
+ unit([x,y])
33
+ end
34
+
35
+ array.should == [[0, 3], [1, 2], [2, 1], [3, 0]]
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'do_notation/monads/simulations'
3
+
4
+ roll_3d6 = proc do
5
+ d1 <- rand(6)
6
+ d2 <- rand(6)
7
+ d3 <- rand(6)
8
+
9
+ unit(1+d1 + 1+d2 + 1+d3)
10
+ end
11
+
12
+ roll_3d6_b = proc do
13
+ d1 <- rand(6)
14
+ d2 <- rand(6)
15
+ d3 <- rand(6)
16
+
17
+ if [d1, d2, d3].include?(5)
18
+ run do
19
+ d4 <- rand(6)
20
+ unit(1+d1 + 1+d2 + 1+d3 + 1+d4)
21
+ end
22
+ else
23
+ unit(1+d1 + 1+d2 + 1+d3)
24
+ end
25
+ end
26
+
27
+ describe "Simulation" do
28
+ specify "generates correct answers" do
29
+ Simulation.run(&roll_3d6).play.should == 9
30
+ Simulation.run(&roll_3d6_b).play.should == 9
31
+ end
32
+ end
33
+
34
+ describe "Distribution" do
35
+ specify "generates correct answers" do
36
+ Distribution.run(&roll_3d6).play.inspect.should == "[[3, 0.00462962962962963], [4, 0.0138888888888889], [5, 0.0277777777777778], [6, 0.0462962962962963], [7, 0.0694444444444444], [8, 0.0972222222222222], [9, 0.115740740740741], [10, 0.125], [11, 0.125], [12, 0.115740740740741], [13, 0.0972222222222222], [14, 0.0694444444444444], [15, 0.0462962962962963], [16, 0.0277777777777778], [17, 0.0138888888888889], [18, 0.00462962962962963]]"
37
+ Distribution.run(&roll_3d6_b).play.inspect.should == "[[3, 0.00462962962962963], [4, 0.0138888888888889], [5, 0.0277777777777778], [6, 0.0462962962962963], [7, 0.0694444444444444], [8, 0.0833333333333333], [9, 0.0902777777777777], [10, 0.0902777777777778], [11, 0.0833333333333333], [12, 0.0694444444444445], [13, 0.0625000000000001], [14, 0.0601851851851853], [15, 0.0578703703703705], [16, 0.0555555555555557], [17, 0.0532407407407408], [18, 0.0462962962962964], [19, 0.0354938271604938], [20, 0.0239197530864198], [21, 0.0146604938271605], [22, 0.00771604938271605], [23, 0.00308641975308642], [24, 0.000771604938271605]]"
38
+ end
39
+ end
40
+
41
+ describe "Expectation" do
42
+ specify "generates correct answers" do
43
+ (1..21).collect { |x| Expectation.run(&roll_3d6).play(x) }.inspect.should == "[0.0, 0.0, 0.00462962962962963, 0.0138888888888889, 0.0277777777777778, 0.0462962962962963, 0.0694444444444444, 0.0972222222222222, 0.115740740740741, 0.125, 0.125, 0.115740740740741, 0.0972222222222222, 0.0694444444444444, 0.0462962962962963, 0.0277777777777778, 0.0138888888888889, 0.00462962962962963, 0.0, 0.0, 0.0]"
44
+ (1..21).collect { |x| Expectation.run(&roll_3d6_b).play(x) }.inspect.should == "[0.0, 0.0, 0.00462962962962963, 0.0138888888888889, 0.0277777777777778, 0.0462962962962963, 0.0694444444444444, 0.0833333333333333, 0.0902777777777778, 0.0902777777777777, 0.0833333333333333, 0.0694444444444444, 0.0625, 0.0601851851851852, 0.0578703703703704, 0.0555555555555556, 0.0532407407407407, 0.0462962962962963, 0.0354938271604938, 0.0239197530864197, 0.0146604938271605]"
45
+ end
46
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), %w(.. lib do_notation))
@@ -0,0 +1,66 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require 'do_notation/monads/array'
3
+
4
+ describe "Monad.run" do
5
+ specify "should have lexical scope" do
6
+ foo = "cousin"
7
+ bar = "removed"
8
+
9
+ array = Array.run do
10
+ x <- ["first", "second"]
11
+ y <- ["once", "twice"]
12
+
13
+ unit("#{x} #{foo} #{y} #{bar}")
14
+ end
15
+
16
+ array.should == ["first cousin once removed",
17
+ "first cousin twice removed",
18
+ "second cousin once removed",
19
+ "second cousin twice removed"]
20
+ end
21
+
22
+ specify "should be nestable" do
23
+ array = Array.run do
24
+ x <- run do
25
+ a <- ['A','a']
26
+ b <- ['B','b']
27
+
28
+ unit(a+b)
29
+ end
30
+
31
+ y <- run do
32
+ c <- ['C','c']
33
+ d <- ['D','d']
34
+
35
+ unit(c+d)
36
+ end
37
+
38
+ unit(x+y)
39
+ end
40
+
41
+ array.should == ["ABCD", "ABCd", "ABcD", "ABcd",
42
+ "AbCD", "AbCd", "AbcD", "Abcd",
43
+ "aBCD", "aBCd", "aBcD", "aBcd",
44
+ "abCD", "abCd", "abcD", "abcd"]
45
+ end
46
+ end
47
+
48
+ describe 'Monad#>>' do
49
+ specify "should compose two values, discarding the first" do
50
+ ([1] >> [2]).should == [2]
51
+ end
52
+ end
53
+
54
+ describe "Rewriter.pp" do
55
+ specify "should produce correct output" do
56
+ array = [:a, [:b],
57
+ [:c, :d,
58
+ :e]]
59
+
60
+ Rewriter.pp(array).should == <<CODE.strip
61
+ (:a (:b)
62
+ (:c :d
63
+ :e))
64
+ CODE
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: GTof-ruby-do-notation
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.2"
5
+ platform: ruby
6
+ authors:
7
+ - Aanand Prasad
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-03 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ParseTree
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: ruby2ruby
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: echoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ description: Haskell-style monad do-notation for Ruby
43
+ email: aanand.prasad@gmail.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - lib/do_notation/monad.rb
50
+ - lib/do_notation/monad_plus.rb
51
+ - lib/do_notation/monads/array.rb
52
+ - lib/do_notation/monads/maybe.rb
53
+ - lib/do_notation/monads/simulations.rb
54
+ - lib/do_notation/rewriter.rb
55
+ - lib/do_notation.rb
56
+ - README.markdown
57
+ files:
58
+ - lib/do_notation/monad.rb
59
+ - lib/do_notation/monad_plus.rb
60
+ - lib/do_notation/monads/array.rb
61
+ - lib/do_notation/monads/maybe.rb
62
+ - lib/do_notation/monads/simulations.rb
63
+ - lib/do_notation/rewriter.rb
64
+ - lib/do_notation.rb
65
+ - README.markdown
66
+ - test/array.rb
67
+ - test/maybe.rb
68
+ - test/monad_plus.rb
69
+ - test/simulations.rb
70
+ - test/spec_helper.rb
71
+ - test/specs.rb
72
+ - Manifest
73
+ - ruby-do-notation.gemspec
74
+ - Rakefile
75
+ has_rdoc: true
76
+ homepage: http://github.com/aanand/ruby-do-notation/tree/master
77
+ post_install_message:
78
+ rdoc_options:
79
+ - --line-numbers
80
+ - --inline-source
81
+ - --title
82
+ - Ruby-do-notation
83
+ - --main
84
+ - README.markdown
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ version:
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "1.2"
98
+ version:
99
+ requirements: []
100
+
101
+ rubyforge_project: ruby-do-notation
102
+ rubygems_version: 1.2.0
103
+ signing_key:
104
+ specification_version: 2
105
+ summary: Haskell-style monad do-notation for Ruby
106
+ test_files: []
107
+