Permalink
Browse files

Add #fmap to make it more functor-like.

  • Loading branch information...
1 parent 9c4a528 commit c1ae4a27e00c74d405ec13b4871a730f5e746430 @mike-burns mike-burns committed Jul 29, 2011
Showing with 30 additions and 1 deletion.
  1. +7 −1 README.md
  2. +8 −0 lib/wrapped/types.rb
  3. +15 −0 spec/wrapped_spec.rb
View
@@ -92,7 +92,7 @@ Cool Stuff
----------
A wrapped value mixes in Enumerable. The functional world would say "that's a
-functor!". They're right.
+functor!". They're close enough.
This means that you can `map`, `inject`, `to_a`, `any?`, and so on over your
wrapped value. By wrapping it you've just made it more powerful!
@@ -113,6 +113,12 @@ Those same people who will exclaim things about functors will, at this point,
get giddy about monads. I mean, they're right, but they can relax. It's just a
monad.
+Those people ("what do you mean, 'those people'?!") may prefer the `fmap`
+method:
+
+ irb> 1.wrapped.fmap {|n| n+1}.unwrap_or(0) {|n| n+4}
+ => 6
+
Other Methods
-------------
View
@@ -42,6 +42,10 @@ def blank?
def try
yield unwrap
end
+
+ def fmap
+ (yield unwrap).wrapped
+ end
end
class Blank
@@ -79,4 +83,8 @@ def blank?
def try
self
end
+
+ def fmap
+ self
+ end
end
View
@@ -73,6 +73,7 @@
# This behavior is different from Haskell and Scala.
# It is done this way for consistency with Ruby.
+# See the functor description later for `fmap'.
describe Wrapped, 'enumerable' do
let(:value) { 1 }
let(:just) { 1.wrapped }
@@ -158,3 +159,17 @@
nothing.try {|n| (n+1).wrapped}.should be_blank
end
end
+
+describe Wrapped, 'functor' do
+ let(:value) { 1 }
+ let(:just) { 1.wrapped }
+ let(:nothing) { nil.wrapped }
+
+ it 'unwraps, applies the block, then re-wraps for a wrapped value' do
+ just.fmap {|n| n+1}.unwrap.should == value+1
+ end
+
+ it 'produces the blank for a wrapped nil' do
+ nothing.fmap {|n| n+1}.should be_blank
+ end
+end

0 comments on commit c1ae4a2

Please sign in to comment.