ruby-maybe 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c18c0a9b1364479ee30af4cd0dd677e6d0d2834
4
- data.tar.gz: 645ef3b0d3b468777dc58488c846c1bb1d869958
3
+ metadata.gz: c9211030f655e23153727e36d2a68d930b54593e
4
+ data.tar.gz: 5c6cd1eb7a99765baa024d45de70d928f9ba88c8
5
5
  SHA512:
6
- metadata.gz: c62cb16a1ca0177720af7c3c0e646c5ed80f73612522d9e862616c0282be813a639d6d1e2a1bb17b8f283c141625f331f1a84c8f56f20cc9c0e617c8a58e8b70
7
- data.tar.gz: b176635e49c8e5b7e173f636245ccbe939eff8a4add5c3e794d74d777c744d6cb1769085e71c1f727db08e50b393be0504ae2a8e01be93040bb48df01f9b3ea6
6
+ metadata.gz: 31eafb9088606234257ed2d151cb3f78712f57ddee187b74f58d1a02a8f185a6ea40efd5e37cf07586a51f57e9dcea5fe8c4023af4b297956500ed3f50d950a1
7
+ data.tar.gz: fbc6e39d5d9cef5c25a515c1a99948b4d1cec192192670ddd60d96a479d0db77dbef4f4dfeb8487b2ce681a88152f2aeb31f522998828026533677e5b11147d0
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - ruby-head
5
+ - jruby-head
data/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ The MIT License (MIT) Copyright (c) Callum Stott, http://www.seadowg.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # ruby-maybe
2
2
 
3
- [![Build Status](https://travis-ci.org/oetzi/ruby-maybe.png?branch=master)](https://travis-ci.org/oetzi/ruby-maybe)
3
+ [![Build Status](https://travis-ci.org/seadowg/ruby-maybe.png?branch=master)](https://travis-ci.org/seadowg/ruby-maybe)
4
4
 
5
5
  ![](http://f.cl.ly/items/2o2A3k1N2d3a1b0V3V0T/maybe.png)
6
6
 
7
7
  ## Description
8
8
 
9
+ ### The Basics
10
+
9
11
  'Maybe' not 'Maeby'. This is an implementation of the 'Maybe' or 'Option' monad similar to that used
10
12
  [Haskell](http://www.haskell.org/haskellwiki/Maybe). Monads provide a
11
13
  safe way to create non deterministic programs (for example, when not all
@@ -53,7 +55,41 @@ without having them throw exceptions or simply return `nil`.
53
55
 
54
56
  `Maybe` is a very basic monad and at first might not seem that powerful
55
57
  but after using it instead of the more verbose control flow it replaces
56
- I think you might learn to love it.
58
+ you might just learn to love it.
59
+
60
+ ### Method Lifting
61
+
62
+ Ok so using `bind` to operate on Maybe is all well and good, but what if
63
+ you want to add three Maybe's together:
64
+
65
+ x.bind { |x_val|
66
+ y.bind { |y_val|
67
+ z.bind { |z_val|
68
+ Just.new(x + y + z)
69
+ }
70
+ }
71
+ }
72
+
73
+ Yeah... I don't think so. In languages like Haskell we can use [Applicative Functors](http://learnyouahaskell.com/functors-applicative-functors-and-monoids)
74
+ to deal with making expressions like the above less verbose. You can go read about them but that's not really important.
75
+ With ruby-maybe methods on the contained object in a Maybe can be lifted to operate on the Maybe:
76
+
77
+ Just.new(5) + Just.new(6) # => Just.new(11)
78
+ Just.new("OMG").downcase # => Just.new("omg")
79
+ Just.new([1,2]).inject(Just.new(0), :+) # => Just.new(3)
80
+
81
+ All operations can be lifted like this and you can mix and match actual values and Maybes in the arguments. This also
82
+ works for Nothing:
83
+
84
+ Nothing.new + Just.new(5) # => Nothing.new
85
+ Just.new(0) * Nothing.new / Just.new(1) # => Nothing.new
86
+
87
+ ### Extracting Values from a Maybe
88
+
89
+ Try not to do this. Please. Monads are best used when we play nice and let the Monad look after our values. Of course,
90
+ you're thinking "well at some point I have to take it out to write it out or stick it in a web response on something
91
+ right?". Yes, of course. But its best if these cases have abstractions that can receive monads or are structured as
92
+ Monads themselves (some languages like Haskell include Monads for IO, Web request processing [etc](http://learnyouahaskell.com/a-fistful-of-monads)).
57
93
 
58
94
  ## Installation
59
95
 
data/lib/ruby-maybe.rb CHANGED
@@ -1,17 +1,10 @@
1
1
  class Maybe
2
- def method_missing(method_name, *args, &block)
3
- Maybe.new
4
- end
5
-
6
- def bind(&block)
7
- Maybe.new
8
- end
9
2
  end
10
3
 
11
4
  class Just < Maybe
12
5
  def method_missing(method_name, *args, &block)
13
6
  values = args.map { |arg|
14
- return Nothing.new if arg == Nothing.new
7
+ return Nothing.new if arg == Nothing.new
15
8
  arg.kind_of?(Just) ? arg.value : arg
16
9
  }
17
10
 
@@ -23,9 +16,9 @@ class Just < Maybe
23
16
  end
24
17
 
25
18
  def bind(&block)
26
- value = block.call(@value)
27
- warn("Not returning a Maybe from #bind is really bad form...") unless value.kind_of?(Maybe)
28
- value
19
+ computed = block.call(@value)
20
+ warn("Not returning a Maybe from #bind is really bad form...") unless computed.kind_of?(Maybe)
21
+ computed
29
22
  end
30
23
 
31
24
  def ==(object)
@@ -36,6 +29,10 @@ class Just < Maybe
36
29
  end
37
30
  end
38
31
 
32
+ def _extract!
33
+ value
34
+ end
35
+
39
36
  protected
40
37
 
41
38
  def value
@@ -59,4 +56,14 @@ class Nothing < Maybe
59
56
  false
60
57
  end
61
58
  end
59
+
60
+ def _extract!
61
+ raise AttemptedExtract.new
62
+ end
63
+
64
+ class AttemptedExtract < Exception
65
+ def initialize
66
+ super("Attempted to extract value from Nothing")
67
+ end
68
+ end
62
69
  end
data/ruby-maybe.gemspec CHANGED
@@ -3,11 +3,12 @@ $:.unshift lib unless $:.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ruby-maybe"
6
- s.version = "0.1.1"
6
+ s.version = "0.2.0"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Callum Stott"]
9
- s.email = ["callum.stott@me.com"]
9
+ s.email = ["callum@seadowg"]
10
10
  s.summary = "Maybe monad implementation for Ruby"
11
+ s.license = 'MIT'
11
12
 
12
13
  s.require_paths = ['lib']
13
14
  s.files = `git ls-files`.split("\n")
@@ -41,6 +41,12 @@ describe "Just" do
41
41
  count.must_equal(10)
42
42
  end
43
43
  end
44
+
45
+ describe "#_extract!" do
46
+ it "returns the contained value" do
47
+ Just.new(5)._extract!.must_equal(5)
48
+ end
49
+ end
44
50
  end
45
51
 
46
52
  describe "Nothing" do
@@ -71,24 +77,12 @@ describe "Nothing" do
71
77
  Nothing.new.missing.must_equal(Nothing.new)
72
78
  end
73
79
  end
74
- end
75
-
76
- describe "Maybe" do
77
- describe "#bind" do
78
- it "does not execute the passed block" do
79
- executed = false
80
- Maybe.new.bind { |val| executed = true }
81
- executed.must_equal false
82
- end
83
-
84
- it "returns a Maybe" do
85
- Maybe.new.bind { |val| val }.kind_of?(Maybe).must_equal true
86
- end
87
- end
88
80
 
89
- describe "method lifting" do
90
- it "returns Maybe for any method call" do
91
- Maybe.new.missing.kind_of?(Maybe).must_equal(true)
81
+ describe "#_extract!" do
82
+ it "raises an exception" do
83
+ assert_raises(Nothing::AttemptedExtract) {
84
+ Nothing.new._extract!
85
+ }
92
86
  end
93
87
  end
94
88
  end
metadata CHANGED
@@ -1,32 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-maybe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Callum Stott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-08 00:00:00.000000000 Z
11
+ date: 2013-05-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
15
- - callum.stott@me.com
15
+ - callum@seadowg
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - .gitignore
21
+ - .travis.yml
21
22
  - Gemfile
22
23
  - Gemfile.lock
24
+ - LICENSE.md
23
25
  - README.md
24
26
  - Rakefile
25
27
  - lib/ruby-maybe.rb
26
28
  - ruby-maybe.gemspec
27
29
  - spec/ruby-maybe_spec.rb
28
30
  homepage:
29
- licenses: []
31
+ licenses:
32
+ - MIT
30
33
  metadata: {}
31
34
  post_install_message:
32
35
  rdoc_options: []