kleisli 0.2.0 → 0.2.1

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
- ---
2
- SHA1:
3
- metadata.gz: 997aca6d77f858cf9262df7edbc913179cd8004f
4
- data.tar.gz: dac24d37b400e98703e6299fb6a702ea5df773eb
5
- SHA512:
6
- metadata.gz: 009f9357a66c1003610f90cd86e734c00632efa6b8b511d5eec2bdc91daceb41bc3f1ebf667615065aefd506435510f8de97a83518a2e6259241f649224d0fef
7
- data.tar.gz: 77f136e1fb92e6d315c7b423aa2c5e8f32b3f3f1f2ec0071488c51557cab9d52d51a3d6b1f105211f2525979825456a4ea09ea53aa78d6e0b2809ffa581f9ec7
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0edc56dbf5e93057c443c0957b312524b8d20d7d
4
+ data.tar.gz: dee2ed0829f1ad9c4ad19f15a8f86293a79e2363
5
+ SHA512:
6
+ metadata.gz: 890887f61bd1b551028fea3384da9654e5394fa4da1ee993d3bf77ac5f43befe3b7ec64cd28002178dc933952cf0ecc638c694c37a88d87a64bcfeddfed1d068
7
+ data.tar.gz: 513db7d077f6061c734c6cde0fa7ccee7ba94e64b8b5195cce1d49642311ec4360c96dffba20cd44ef86b914d5aae0ae1461a86bf42e85fdbb12f8042873a623
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Kleisli [![Build Status](https://secure.travis-ci.org/txus/adts.png)](http://travis-ci.org/txus/adts)
1
+ # Kleisli [![Build Status](https://secure.travis-ci.org/txus/kleisli.png)](http://travis-ci.org/txus/kleisli)
2
2
 
3
3
  An idiomatic, clean implementation of a few common useful monads in Ruby,
4
4
  written by [Ryan Levick][rylev] and me.
@@ -68,7 +68,7 @@ f.call " localhost:9092 "
68
68
 
69
69
  # Partially applied lambda:
70
70
  my_split = lambda { |str, *args| str.split(*args) }
71
- f = F . fn(":", &split)
71
+ f = F . fn(":", &my_split) . strip
72
72
  f.call " localhost:9092 "
73
73
  # => ["localhost", "9092"]
74
74
  ```
@@ -261,7 +261,7 @@ require "kleisli"
261
261
 
262
262
  add = -> x, y { x + y }
263
263
  Right(add) * Right(10) * Right(2)
264
- # => Some(12)
264
+ # => Right(12)
265
265
  Right(add) * Left("error") * Right(2)
266
266
  # => Left("error")
267
267
  ```
@@ -298,46 +298,6 @@ result # => Some(10)
298
298
  result # => None()
299
299
  ```
300
300
 
301
- ## Writer
302
-
303
- The Writer monad is arguably the least useful monad in Ruby (as side effects
304
- are uncontrolled), but let's take a look at it anyway.
305
-
306
- It is used to model computations that *append* to some kind of state (which
307
- needs to be a Monoid, expressed in the `Kleisli::Monoid` mixin) at each step.
308
-
309
- (We've already implemented the Monoid interface for `String`, `Array`, `Hash`,
310
- `Fixnum` and `Float` for you.)
311
-
312
- An example would be a pipeline of computations that append to a log, for
313
- example a list of strings.
314
-
315
- ### `>->` (bind)
316
-
317
- ```ruby
318
- require "kleisli"
319
-
320
- writer = Writer([], 100) >-> value {
321
- Writer(["added 100"], value + 100)
322
- } >-> value {
323
- Writer(["added 140 more"], value + 140)
324
- } # => Writer(["added 100", "added 140 more"], 340)
325
-
326
- log, value = writer.unwrap
327
- log # => ["added 100", "added 140 more"]
328
- value # => 340
329
- ```
330
-
331
- ### `fmap`
332
-
333
- ```ruby
334
- require "kleisli"
335
-
336
- writer = Writer([], 100).fmap { |value|
337
- value + 100
338
- } # => Writer([], 200)
339
- ```
340
-
341
301
  ## Future
342
302
 
343
303
  The Future monad models a pipeline of computations that will happen in the future, as soon as the value needed for each step is available. It is useful to model, for example, a sequential chain of HTTP calls.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require "rake/testtask"
3
3
 
4
4
  Rake::TestTask.new do |t|
5
5
  t.libs << "test"
6
- t.test_files = FileList['test/**/*.rb']
6
+ t.test_files = FileList['test/**/*_test.rb']
7
7
  t.verbose = true
8
8
  end
9
9
 
data/kleisli.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest", "~> 5.5"
23
24
  end
data/lib/kleisli.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "kleisli/version"
2
2
  require "kleisli/maybe"
3
3
  require "kleisli/try"
4
- require "kleisli/writer"
5
4
  require "kleisli/future"
6
5
  require "kleisli/either"
7
6
  require "kleisli/composition"
data/lib/kleisli/blank.rb CHANGED
@@ -24,7 +24,7 @@ class Blank
24
24
  def hide(name)
25
25
  methods = instance_methods.map(&:to_sym)
26
26
  if methods.include?(name.to_sym) and
27
- name !~ /^(__|instance_eval)/
27
+ name !~ /^(__|instance_eval|object_id)/
28
28
  @hidden_methods ||= {}
29
29
  @hidden_methods[name.to_sym] = instance_method(name)
30
30
  undef_method name
@@ -1,18 +1,10 @@
1
1
  require_relative 'blank'
2
2
 
3
- class Proc
4
- def self.comp(f, g)
5
- lambda { |*args| f[g[*args]] }
6
- end
7
-
8
- def *(g)
9
- Proc.comp(self, g)
10
- end
11
- end
12
-
13
3
  module Kleisli
14
4
  class ComposedFn < Blank
15
- include ::Kernel
5
+ def self.comp(f, g)
6
+ lambda { |*args| f[g[*args]] }
7
+ end
16
8
 
17
9
  def initialize(fns=[])
18
10
  @fns = fns
@@ -34,7 +26,7 @@ module Kleisli
34
26
 
35
27
  def call(*args)
36
28
  if @fns.any?
37
- @fns.reduce(:*).call(*args)
29
+ @fns.reduce { |f, g| ComposedFn.comp(f, g) }.call(*args)
38
30
  else
39
31
  args.first
40
32
  end
@@ -1,3 +1,3 @@
1
1
  module Kleisli
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class CompositionTest < MiniTest::Unit::TestCase
3
+ class CompositionTest < Minitest::Test
4
4
  def test_one_method
5
5
  f = F . first
6
6
  result = f.call([1])
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class EitherTest < MiniTest::Unit::TestCase
3
+ class EitherTest < Minitest::Test
4
4
  def test_lift_right
5
5
  assert_equal 3, Right(3).value
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class FutureTest < MiniTest::Unit::TestCase
3
+ class FutureTest < Minitest::Test
4
4
  def test_immediate_value
5
5
  assert_equal 30, Future(30).await
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class MaybeTest < MiniTest::Unit::TestCase
3
+ class MaybeTest < Minitest::Test
4
4
  def test_unwrapping_some
5
5
  assert_equal 3, Some(3).value
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class TryTest < MiniTest::Unit::TestCase
3
+ class TryTest < Minitest::Test
4
4
  def test_success
5
5
  assert_equal 2, Try { 10 / 5 }.value
6
6
  end
data/test/test_helper.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  require 'kleisli'
2
- require 'test/unit'
2
+ require 'minitest'
3
+ require 'minitest/autorun'
metadata CHANGED
@@ -1,61 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: kleisli
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Josep M. Bach
8
8
  - Ryan Levick
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-22 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
12
+
13
+ date: 2014-12-18 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
15
16
  name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.6'
21
- type: :development
22
17
  prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '1.6'
28
- - !ruby/object:Gem::Dependency
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: "1.6"
23
+ type: :development
24
+ version_requirements: *id001
25
+ - !ruby/object:Gem::Dependency
29
26
  name: rake
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: '10.0'
27
+ prerelease: false
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: "10.0"
35
33
  type: :development
34
+ version_requirements: *id002
35
+ - !ruby/object:Gem::Dependency
36
+ name: minitest
36
37
  prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '10.0'
38
+ requirement: &id003 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: "5.5"
43
+ type: :development
44
+ version_requirements: *id003
42
45
  description: Usable, idiomatic common monads in Ruby
43
- email:
46
+ email:
44
47
  - josep.m.bach@gmail.com
45
48
  - ryan.levick@gmail.com
46
49
  executables: []
50
+
47
51
  extensions: []
52
+
48
53
  extra_rdoc_files: []
49
- files:
50
- - ".gitignore"
51
- - ".travis.yml"
54
+
55
+ files:
56
+ - .gitignore
57
+ - .travis.yml
52
58
  - Gemfile
53
59
  - LICENSE.txt
54
60
  - README.md
55
61
  - Rakefile
56
62
  - kleisli.gemspec
57
63
  - lib/kleisli.rb
58
- - lib/kleisli/applicative_functor.rb
59
64
  - lib/kleisli/blank.rb
60
65
  - lib/kleisli/composition.rb
61
66
  - lib/kleisli/either.rb
@@ -63,48 +68,44 @@ files:
63
68
  - lib/kleisli/future.rb
64
69
  - lib/kleisli/maybe.rb
65
70
  - lib/kleisli/monad.rb
66
- - lib/kleisli/monoid.rb
67
71
  - lib/kleisli/try.rb
68
72
  - lib/kleisli/version.rb
69
- - lib/kleisli/writer.rb
70
73
  - test/kleisli/composition_test.rb
71
74
  - test/kleisli/either_test.rb
72
75
  - test/kleisli/future_test.rb
73
76
  - test/kleisli/maybe_test.rb
74
- - test/kleisli/monoid_test.rb
75
77
  - test/kleisli/try_test.rb
76
- - test/kleisli/writer_test.rb
77
78
  - test/test_helper.rb
78
79
  homepage: https://github.com/txus/kleisli
79
- licenses:
80
+ licenses:
80
81
  - MIT
81
82
  metadata: {}
83
+
82
84
  post_install_message:
83
85
  rdoc_options: []
84
- require_paths:
86
+
87
+ require_paths:
85
88
  - lib
86
- required_ruby_version: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- required_rubygems_version: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '0'
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - &id004
92
+ - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - *id004
96
98
  requirements: []
99
+
97
100
  rubyforge_project:
98
- rubygems_version: 2.2.2
101
+ rubygems_version: 2.4.4
99
102
  signing_key:
100
103
  specification_version: 4
101
104
  summary: Usable, idiomatic common monads in Ruby
102
- test_files:
105
+ test_files:
103
106
  - test/kleisli/composition_test.rb
104
107
  - test/kleisli/either_test.rb
105
108
  - test/kleisli/future_test.rb
106
109
  - test/kleisli/maybe_test.rb
107
- - test/kleisli/monoid_test.rb
108
110
  - test/kleisli/try_test.rb
109
- - test/kleisli/writer_test.rb
110
111
  - test/test_helper.rb
@@ -1,4 +0,0 @@
1
- module Kleisli
2
- class ApplicativeFunctor < Functor
3
- end
4
- end
@@ -1,65 +0,0 @@
1
- module Kleisli
2
- module Monoid
3
- def fold(others)
4
- others.reduce(self) { |acc, x| acc.mappend x }
5
- end
6
-
7
- def mempty
8
- raise NotImplementedError, "this monoid doesn't implement mpemty"
9
- end
10
-
11
- def mappend(other)
12
- raise NotImplementedError, "this monoid doesn't implement mappend"
13
- end
14
- end
15
- end
16
-
17
- String.class_eval do
18
- include Kleisli::Monoid
19
-
20
- def mempty
21
- ""
22
- end
23
-
24
- alias mappend +
25
- end
26
-
27
- Array.class_eval do
28
- include Kleisli::Monoid
29
-
30
- def mempty
31
- []
32
- end
33
-
34
- alias mappend +
35
- end
36
-
37
- Hash.class_eval do
38
- include Kleisli::Monoid
39
-
40
- def mempty
41
- {}
42
- end
43
-
44
- alias mappend merge
45
- end
46
-
47
- Fixnum.class_eval do
48
- include Kleisli::Monoid
49
-
50
- def mempty
51
- 0
52
- end
53
-
54
- alias mappend +
55
- end
56
-
57
- Float.class_eval do
58
- include Kleisli::Monoid
59
-
60
- def mempty
61
- 0
62
- end
63
-
64
- alias mappend +
65
- end
@@ -1,36 +0,0 @@
1
- require 'kleisli/monad'
2
- require 'kleisli/monoid'
3
-
4
- module Kleisli
5
- class Writer < Monad
6
- def self.lift(log, value)
7
- new(log, value)
8
- end
9
-
10
- def initialize(log, value)
11
- @log, @value = log, value
12
- end
13
-
14
- def ==(other)
15
- unwrap == other.unwrap
16
- end
17
-
18
- def >(f)
19
- other_log, other_value = f.call(@value).unwrap
20
- Writer.new(@log + other_log, other_value)
21
- end
22
-
23
- def fmap(&f)
24
- new_value = f.call(@value)
25
- Writer.new(@log, new_value)
26
- end
27
-
28
- def unwrap
29
- [@log, @value]
30
- end
31
- end
32
- end
33
-
34
- def Writer(log, value)
35
- Kleisli::Writer.lift(log, value)
36
- end
@@ -1,23 +0,0 @@
1
- require 'test_helper'
2
-
3
- class MonoidTest < MiniTest::Unit::TestCase
4
- def test_string_fold
5
- assert_equal "hellogoodbye", "hello".fold(%w(good bye))
6
- end
7
-
8
- def test_array_fold
9
- assert_equal [1, 2, 3], [1].fold([[2], [3]])
10
- end
11
-
12
- def test_hash_fold
13
- assert_equal({a: 1, b: 2, c: 3}, {a: 1}.fold([{b: 2}, {c: 3}]))
14
- end
15
-
16
- def test_fixnum_fold
17
- assert_equal 6, 1.fold([2,3])
18
- end
19
-
20
- def test_float_fold
21
- assert_equal 6.0, 1.0.fold([2.0,3.0])
22
- end
23
- end
@@ -1,19 +0,0 @@
1
- require 'test_helper'
2
-
3
- class WriterTest < MiniTest::Unit::TestCase
4
- def test_unwrap
5
- log, value = Writer("log", 100).unwrap
6
- assert_equal "log", log
7
- assert_equal 100, value
8
- end
9
-
10
- def test_bind
11
- writer = Writer("foo", 100) >-> value { Writer("bar", value + 100) }
12
- assert_equal Writer("foobar", 200), writer
13
- end
14
-
15
- def test_fmap
16
- writer = Writer("foo", 100).fmap { |value| value + 100 }
17
- assert_equal Writer("foo", 200), writer
18
- end
19
- end