dry-monads 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88cbc378229c970ceaee7b5836e049e9802fa673
4
+ data.tar.gz: 1bb1cb7d186fe287406f2be34a5f068a29d2edde
5
+ SHA512:
6
+ metadata.gz: 15a531580dda1dd1ae4d2a18da1ef0bc9d15925001fecad504276aceedf27619635620646c8f003b24f7282d2825f4ec65619a6bc30c656fc508c7259ffbc501
7
+ data.tar.gz: 9f71fc354106893b2b95f1f082014435cc3a74443b13812b8141f7c44b8007034ea2f77c5f7aa5e6c41b8214804af105cffcf8c559da6e98917a5633edb37b28
data/.codeclimate.yml ADDED
@@ -0,0 +1,41 @@
1
+ engines:
2
+ rubocop:
3
+ enabled: true
4
+ checks:
5
+ Rubocop/Style/Documentation:
6
+ enabled: false
7
+ Rubocop/Style/StringLiterals:
8
+ enabled: false
9
+ Rubocop/Style/MethodName:
10
+ enabled: false
11
+ Rubocop/Style/LambdaCall:
12
+ enabled: false
13
+ Rubocop/Style/StabbyLambdaParentheses:
14
+ enabled: false
15
+ Rubocop/Style/NestedParenthesizedCalls:
16
+ enabled: false
17
+ Rubocop/Style/MultilineBlockChain:
18
+ enabled: false
19
+ Rubocop/Style/GuardClause:
20
+ enabled: false
21
+ Rubocop/Metrics/LineLength:
22
+ enabled: true
23
+ max: 110
24
+ Rubocop/Style/FileName:
25
+ enabled: true
26
+ exclude:
27
+ - 'lib/dry-monads.rb'
28
+ Rubocop/Lint/Debugger:
29
+ enabled: true
30
+ exclude:
31
+ - 'bin/console'
32
+ Rubocop/Lint/HandleExceptions:
33
+ enabled: true
34
+ exclude:
35
+ - 'spec/spec_helper.rb'
36
+ ratings:
37
+ paths:
38
+ - lib/**/*.rb
39
+ exclude_paths:
40
+ - spec/**/*
41
+ - examples/**/*
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,40 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Style/Documentation:
4
+ Enabled: false
5
+
6
+ Style/StringLiterals:
7
+ Enabled: false
8
+
9
+ Style/MethodName:
10
+ Enabled: false
11
+
12
+ Style/LambdaCall:
13
+ Enabled: false
14
+
15
+ Style/StabbyLambdaParentheses:
16
+ Enabled: false
17
+
18
+ Style/NestedParenthesizedCalls:
19
+ Enabled: false
20
+
21
+ Style/MultilineBlockChain:
22
+ Enabled: false
23
+
24
+ Style/GuardClause:
25
+ Enabled: false
26
+
27
+ Metrics/LineLength:
28
+ Max: 110
29
+
30
+ Style/FileName:
31
+ Exclude:
32
+ - 'lib/dry-monads.rb'
33
+
34
+ Lint/Debugger:
35
+ Exclude:
36
+ - 'bin/console'
37
+
38
+ Lint/HandleExceptions:
39
+ Exclude:
40
+ - 'spec/spec_helper.rb'
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,7 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2016-04-29 01:33:48 +0100 using RuboCop version 0.39.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
data/.travis.yml ADDED
@@ -0,0 +1,40 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ bundler_args: --without benchmarks tools
5
+ script:
6
+ - bundle exec rake spec
7
+ rvm:
8
+ - 2.0
9
+ - 2.1
10
+ - 2.2
11
+ - 2.3.0
12
+ - rbx-2
13
+ - jruby-9000
14
+ - ruby-head
15
+ env:
16
+ global:
17
+ - JRUBY_OPTS='--dev -J-Xmx1024M'
18
+ before_install:
19
+ - gem update bundler
20
+ matrix:
21
+ allow_failures:
22
+ - rvm: ruby-head
23
+ - rvm: jruby-head
24
+ include:
25
+ - rvm: jruby-head
26
+ before_install: gem install bundler --no-ri --no-rdoc
27
+
28
+ notifications:
29
+ email:
30
+ recipients:
31
+ - fg@flashgordon.ru
32
+ on_success: change
33
+ on_failure: always
34
+ on_start: false # default: false
35
+ webhooks:
36
+ urls:
37
+ - https://webhooks.gitter.im/e/19098b4253a72c9796db
38
+ on_success: change # options: [always|never|change] default: always
39
+ on_failure: always # options: [always|never|change] default: always
40
+ on_start: false # default: false
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'codeclimate-test-reporter', require: false
7
+ gem 'simplecov', require: false
8
+ end
9
+
10
+ group :tools do
11
+ gem 'rubocop'
12
+ gem 'pry'
13
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013-2014 Piotr Solnica
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,232 @@
1
+ [gitter]: https://gitter.im/dry-rb/chat
2
+ [gem]: https://rubygems.org/gems/dry-monads
3
+ [travis]: https://travis-ci.org/dry-rb/dry-monads
4
+ [code_climate]: https://codeclimate.com/github/dry-rb/dry-monads
5
+ [inch]: http://inch-ci.org/github/dry-rb/dry-monads
6
+
7
+ # dry-monads [![Join the Gitter chat](https://badges.gitter.im/Join%20Chat.svg)][gitter]
8
+
9
+ [![Gem Version](https://img.shields.io/gem/v/dry-monads.svg)][gem]
10
+ [![Build Status](https://img.shields.io/travis/dry-rb/dry-monads.svg)][travis]
11
+ [![Code Climate](https://img.shields.io/codeclimate/github/dry-rb/dry-monads.svg)][code_climate]
12
+ [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/dry-rb/dry-monads.svg)][code_climate]
13
+ [![API Documentation Coverage](http://inch-ci.org/github/dry-rb/dry-monads.svg)][inch]
14
+
15
+ Monads for Ruby.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'dry-monads'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ ```sh
28
+ $ bundle
29
+ ```
30
+
31
+ Or install it yourself as:
32
+
33
+ ```sh
34
+ $ gem install dry-monads
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ### Maybe monad
40
+
41
+ The `Maybe` mondad is used when a series of computations that could return `nil`
42
+ at any point.
43
+
44
+ #### `bind`
45
+
46
+ ```ruby
47
+ require 'dry-monads'
48
+
49
+ M = Dry::Monads
50
+
51
+ maybe_user = M.Maybe(user).bind do |u|
52
+ M.Maybe(user.address).bind do |a|
53
+ M.Maybe(a.street)
54
+ end
55
+ end
56
+
57
+ # If user with address exists
58
+ # => Some("Street Address")
59
+ # If user or address is nil
60
+ # => None()
61
+
62
+ # You also can pass a proc to #bind
63
+
64
+ add_two = -> x { x + 2 }
65
+
66
+ M.Maybe(5).bind(add_two).bind(add_two) # => Some(9)
67
+
68
+ ```
69
+
70
+ #### `fmap`
71
+
72
+ Similar to `bind` but lifts the result for you.
73
+
74
+ ```ruby
75
+ require 'dry-monads'
76
+
77
+ Dry::Monads::Maybe(user).fmap(&:address).fmap(&:street)
78
+
79
+ # If user with address exists
80
+ # => Some("Street Address")
81
+ # If user or address is nil
82
+ # => None()
83
+ ```
84
+
85
+ ### Either monad
86
+
87
+ The `Either` mondad is useful to express a series of computations that might
88
+ return an error object with additional information.
89
+
90
+ The `Either` mixin has two type constructors: `Right` and `Left`. The `Right`
91
+ can be thought of as "everything went right" and the `Left` is used when
92
+ "something has gone wrong".
93
+
94
+ #### `Either::Mixin`
95
+
96
+ ```ruby
97
+ require 'dry-monads'
98
+
99
+ class EitherCalculator
100
+ include Dry::Monads::Either::Mixin
101
+
102
+ attr_accessor :input
103
+
104
+ def calculate
105
+ i = Integer(input)
106
+
107
+ Right(i).bind do |value|
108
+ if value > 1
109
+ Right(value + 3)
110
+ else
111
+ Left("value was less than 1")
112
+ end
113
+ end.bind do |value|
114
+ if value % 2 == 0
115
+ Right(value * 2)
116
+ else
117
+ Left("value was not even")
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ # EitherCalculator instance
124
+ c = EitherCalculator.new
125
+
126
+ # If everything went right
127
+ c.input = 3
128
+ result = c.calculate
129
+ result # => Right(12)
130
+ result.value # => 12
131
+
132
+ # If if failed in the first block
133
+ c.input = 0
134
+ result = c.calculate
135
+ result # => Left("value was less than 1")
136
+ result.value # => "value was less than 1"
137
+
138
+ # if it failed in the second block
139
+ c.input = 2
140
+ result = c.calculate
141
+ result # => Left("value was not even")
142
+ result.value # => "value was not even"
143
+ ```
144
+
145
+ #### `fmap`
146
+
147
+ An example of using `fmap` with `Right` and `Left`.
148
+
149
+ ```ruby
150
+ require 'dry-monads'
151
+
152
+ M = Dry::Monads
153
+
154
+ result = if foo > bar
155
+ M.Right(10)
156
+ else
157
+ M.Left("wrong")
158
+ end.fmap { |x| x * 2 }
159
+
160
+ # If everything went right
161
+ result # => Right(20)
162
+ # If it did not
163
+ result # => Left("wrong")
164
+
165
+ # #fmap accepts proc as well as #bind
166
+
167
+ upcase = :upcase.to_proc
168
+
169
+ M.Right('hello').fmap(upcase) # => Right("HELLO")
170
+ ```
171
+
172
+ #### `or`
173
+
174
+ An example of using `or` with `Right` and `Left`.
175
+
176
+ ```ruby
177
+ M = Dry::Monads
178
+
179
+ M.Right(10).or(M.Right(99)) # => Right(10)
180
+ M.Left("error").or(M.Left("new error")) # => Left("new error")
181
+ M.Left("error").or { |err| M.Left("new #{err}") } # => Left("new error")
182
+ ```
183
+
184
+ #### `to_maybe`
185
+
186
+ Sometimes it's useful to turn an 'Either' into a 'Maybe'
187
+
188
+ ```ruby
189
+ require 'dry-monads'
190
+
191
+ result = if foo > bar
192
+ Dry::Monads.Right(10)
193
+ else
194
+ Dry::Monads.Left("wrong")
195
+ end.to_maybe
196
+
197
+ # If everything went right
198
+ result # => Some(10)
199
+ # If it did not
200
+ result # => None()
201
+ ```
202
+
203
+ ### Try monad
204
+
205
+ Examples of using the `Try` monad.
206
+
207
+ ```ruby
208
+ require 'dry-monads'
209
+
210
+ extend Dry::Monads::Try::Mixin
211
+
212
+ res = Try() { 10 / 2 }
213
+ res.value if res.success?
214
+ # => 5
215
+
216
+ res = Try() { 10 / 0 }
217
+ res.exception if res.failure?
218
+ # => #<ZeroDivisionError: divided by 0>
219
+
220
+ Try(NoMethodError, NotImplementedError) { 10 / 0 }
221
+ # => raise ZeroDivisionError: divided by 0 exception
222
+ ```
223
+
224
+ ## Development
225
+
226
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
227
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
228
+ prompt that will allow you to experiment.
229
+
230
+ ## Contributing
231
+
232
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/dry-rb/dry-monads]().
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'dry-monads'
5
+
6
+ M = Dry::Monads
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ # (If you use this, don't forget to add pry to your Gemfile!)
12
+ require 'pry'
13
+
14
+ binding.pry
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'dry/monads/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'dry-monads'
7
+ spec.version = Dry::Monads::VERSION.dup
8
+ spec.authors = ['Nikita Shilnikov']
9
+ spec.email = ['fg@flashgordon.ru']
10
+ spec.license = 'MIT'
11
+
12
+ spec.summary = 'Common monads for Ruby.'
13
+ spec.description = spec.summary
14
+ spec.homepage = 'https://github.com/dry-rb/dry-monads'
15
+
16
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
17
+ # delete this section to allow pushing this gem to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
20
+ else
21
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_development_dependency 'bundler'
30
+ spec.add_development_dependency 'rake'
31
+ spec.add_development_dependency 'rspec'
32
+ end
data/lib/dry-monads.rb ADDED
@@ -0,0 +1 @@
1
+ require 'dry/monads'
data/lib/dry/monads.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'dry/monads/either'
2
+ require 'dry/monads/maybe'
3
+ require 'dry/monads/try'
4
+
5
+ module Dry
6
+ module Monads
7
+ extend self
8
+
9
+ def Maybe(value)
10
+ Maybe.lift(value)
11
+ end
12
+
13
+ def Some(value)
14
+ Maybe::Some.new(value)
15
+ end
16
+
17
+ def None
18
+ Maybe::Some::None.instance
19
+ end
20
+
21
+ def Right(value)
22
+ Either::Right.new(value)
23
+ end
24
+
25
+ def Left(value)
26
+ Either::Left.new(value)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,100 @@
1
+ module Dry
2
+ module Monads
3
+ class Either
4
+ attr_reader :right, :left
5
+
6
+ def ==(other)
7
+ other.is_a?(Either) && right == other.right && left == other.left
8
+ end
9
+
10
+ def right?
11
+ is_a? Right
12
+ end
13
+ alias success? right?
14
+
15
+ def left?
16
+ is_a? Left
17
+ end
18
+ alias failure? left?
19
+
20
+ class Right < Either
21
+ alias value right
22
+
23
+ def initialize(right)
24
+ @right = right
25
+ end
26
+
27
+ def bind(proc = nil)
28
+ if proc
29
+ proc.call(value)
30
+ else
31
+ yield(value)
32
+ end
33
+ end
34
+
35
+ def fmap(proc = nil, &block)
36
+ Right.new(bind(&(proc || block)))
37
+ end
38
+
39
+ def or(_val = nil)
40
+ self
41
+ end
42
+
43
+ def to_s
44
+ "Right(#{value.inspect})"
45
+ end
46
+ alias inspect to_s
47
+
48
+ def to_maybe
49
+ Maybe::Some.new(value)
50
+ end
51
+ end
52
+
53
+ class Left < Either
54
+ alias value left
55
+
56
+ def initialize(left)
57
+ @left = left
58
+ end
59
+
60
+ def bind(_proc = nil)
61
+ self
62
+ end
63
+
64
+ def fmap(_proc = nil)
65
+ self
66
+ end
67
+
68
+ def or(val = nil)
69
+ if block_given?
70
+ yield(value)
71
+ else
72
+ val
73
+ end
74
+ end
75
+
76
+ def to_s
77
+ "Left(#{value.inspect})"
78
+ end
79
+ alias inspect to_s
80
+
81
+ def to_maybe
82
+ Maybe::None.instance
83
+ end
84
+ end
85
+
86
+ module Mixin
87
+ Right = Right
88
+ Left = Left
89
+
90
+ def Right(value)
91
+ Right.new(value)
92
+ end
93
+
94
+ def Left(value)
95
+ Left.new(value)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,103 @@
1
+ module Dry
2
+ module Monads
3
+ class Maybe
4
+ def self.lift(value)
5
+ if value.nil?
6
+ None.instance
7
+ else
8
+ Some.new(value)
9
+ end
10
+ end
11
+
12
+ def ==(other)
13
+ other.is_a?(Maybe) && value == other.value
14
+ end
15
+
16
+ def none?
17
+ is_a?(None)
18
+ end
19
+
20
+ def some?
21
+ is_a?(Some)
22
+ end
23
+
24
+ class Some < Maybe
25
+ attr_reader :value
26
+
27
+ def initialize(value)
28
+ raise ArgumentError, 'nil cannot be some' if value.nil?
29
+ @value = value
30
+ end
31
+
32
+ def bind(proc = nil)
33
+ if proc
34
+ proc.call(value)
35
+ else
36
+ yield(value)
37
+ end
38
+ end
39
+
40
+ def fmap(proc = nil, &block)
41
+ self.class.lift(bind(&(proc || block)))
42
+ end
43
+
44
+ def or(_val = nil)
45
+ self
46
+ end
47
+
48
+ def to_s
49
+ "Some(#{value.inspect})"
50
+ end
51
+ alias inspect to_s
52
+ end
53
+
54
+ class None < Maybe
55
+ @instance = new
56
+ singleton_class.send(:attr_reader, :instance)
57
+
58
+ def value
59
+ nil
60
+ end
61
+
62
+ def bind(_proc = nil)
63
+ self
64
+ end
65
+
66
+ def fmap(_proc = nil)
67
+ self
68
+ end
69
+
70
+ def or(val = nil)
71
+ if block_given?
72
+ yield(value)
73
+ else
74
+ val
75
+ end
76
+ end
77
+
78
+ def to_s
79
+ 'None'
80
+ end
81
+ alias inspect to_s
82
+ end
83
+
84
+ module Mixin
85
+ Maybe = Maybe
86
+ Some = Some
87
+ None = None
88
+
89
+ def Maybe(value)
90
+ Maybe.lift(value)
91
+ end
92
+
93
+ def Some(value)
94
+ Some.new(value)
95
+ end
96
+
97
+ def None
98
+ None.instance
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,101 @@
1
+ module Dry
2
+ module Monads
3
+ class Try
4
+ attr_reader :exception, :value
5
+
6
+ def self.lift(exceptions, f)
7
+ Success.new(exceptions, f.call)
8
+ rescue *exceptions => e
9
+ Failure.new(e)
10
+ end
11
+
12
+ def success?
13
+ is_a? Success
14
+ end
15
+
16
+ def failure?
17
+ is_a? Failure
18
+ end
19
+
20
+ class Success < Try
21
+ attr_reader :catchable
22
+
23
+ def initialize(exceptions, value)
24
+ @catchable = exceptions
25
+ @value = value
26
+ end
27
+
28
+ def bind(proc = nil)
29
+ if proc
30
+ proc.call(value)
31
+ else
32
+ yield(@value)
33
+ end
34
+ rescue *catchable => e
35
+ Failure.new(e)
36
+ end
37
+
38
+ def fmap(proc = nil, &block)
39
+ Try.lift(catchable, -> { (block || proc).call(@value) })
40
+ end
41
+
42
+ def ==(other)
43
+ other.is_a?(Success) && @value == other.value && @catchable == other.catchable
44
+ end
45
+
46
+ def to_maybe
47
+ Dry::Monads::Maybe(@value)
48
+ end
49
+
50
+ def to_either
51
+ Dry::Monads::Right(@value)
52
+ end
53
+
54
+ def to_s
55
+ "Try::Success(#{value.inspect})"
56
+ end
57
+ alias inspect to_s
58
+ end
59
+
60
+ class Failure < Try
61
+ def initialize(exception)
62
+ @exception = exception
63
+ end
64
+
65
+ def bind(_f = nil)
66
+ self
67
+ end
68
+
69
+ def fmap(_f = nil)
70
+ self
71
+ end
72
+
73
+ def to_maybe
74
+ Dry::Monads::None()
75
+ end
76
+
77
+ def to_either
78
+ Dry::Monads::Left(@exception)
79
+ end
80
+
81
+ def ==(other)
82
+ other.is_a?(Failure) && @exception == other.exception
83
+ end
84
+
85
+ def to_s
86
+ "Try::Failure(#{exception.class}: #{exception.message})"
87
+ end
88
+ alias inspect to_s
89
+ end
90
+
91
+ module Mixin
92
+ Try = Try
93
+
94
+ def Try(*exceptions, &f)
95
+ catchable = exceptions.any? ? exceptions.flatten : [StandardError]
96
+ Try.lift(catchable, f)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module Dry
2
+ module Monads
3
+ VERSION = '0.0.1'.freeze
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dry-monads
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nikita Shilnikov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Common monads for Ruby.
56
+ email:
57
+ - fg@flashgordon.ru
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".codeclimate.yml"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".rubocop.yml"
66
+ - ".rubocop_todo.yml"
67
+ - ".travis.yml"
68
+ - Gemfile
69
+ - LICENSE
70
+ - README.md
71
+ - Rakefile
72
+ - bin/console
73
+ - bin/setup
74
+ - dry-monads.gemspec
75
+ - lib/dry-monads.rb
76
+ - lib/dry/monads.rb
77
+ - lib/dry/monads/either.rb
78
+ - lib/dry/monads/maybe.rb
79
+ - lib/dry/monads/try.rb
80
+ - lib/dry/monads/version.rb
81
+ homepage: https://github.com/dry-rb/dry-monads
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ allowed_push_host: https://rubygems.org
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.5.1
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Common monads for Ruby.
106
+ test_files: []