t_algebra 0.1.1 → 0.1.5

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
  SHA256:
3
- metadata.gz: 47c013dcdeaf282791c7043884001899230c9d47bd4e33b27b25654982bd59e1
4
- data.tar.gz: 3d063906d1a462276f0a8ab12bb09cfb5ded2b9e6b9630206b5b81966784d750
3
+ metadata.gz: 617977f1693f665231e2b42e517fc64a92de79bbe8824408501586b992308988
4
+ data.tar.gz: d953427b001daff3bbfab23e94ce46fcd61c8a386f891d14019312d0ae37ddca
5
5
  SHA512:
6
- metadata.gz: b16ffc8e653ff03cc6128863943c41367be132d4218041a9e636ce74495e7657a6468146449c12661d1dc4f66be2e2ac6e3342e31bb6677a20b36a267d44cc4d
7
- data.tar.gz: 7070554503dcec80113967176aa703481989aa716d8758f28bb07ae8b1e7e5a42acd94f84a399e7ad393d53c2526f61a0f1cb5f8ec2121864674d2f80fdd90a3
6
+ metadata.gz: 98fb648dfe43e767057bf50f1479ace8a777b01bf0803b46b9e29c8668aaea8f8464014a7282c74796d1d635b2c4afddec828fb5e85d07c0be44ff6fc85595f0
7
+ data.tar.gz: e9ac940c79d2906bf4f27c902474966e8175e1497b98579a0793400f374568c2022f7f804014ba3fd8bbc9f7ddfa84de46ff75dca0b42da9943a0a482d554f15
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- t_algebra (0.1.0)
4
+ t_algebra (0.1.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -50,9 +50,10 @@ to reproduce the same functionality:
50
50
  # @return [TAlgebra::Monad::Maybe]
51
51
  def get_address(user)
52
52
  TAlgebra::Monad::Maybe.run do |y|
53
- street = y.yield { to_maybe(user.street) }
54
- city = y.yield { to_maybe(user.city) }
55
- state = y.yield { to_maybe(user.state) }
53
+ m_user = just(user)
54
+ street = y.yield { m_user.fetch(:street) }
55
+ city = y.yield { m_user.fetch(:city) }
56
+ state = y.yield { m_user.fetch(:state) }
56
57
  "#{street}, #{city} #{state.upcase}"
57
58
  end
58
59
  end
@@ -17,16 +17,18 @@ module TAlgebra
17
17
  end
18
18
  end
19
19
 
20
- def fmap(&block)
21
- return dup if left? || !block
20
+ def fmap
21
+ raise UseError.new("#fmap requires a block") unless block_given?
22
+ return dup if left?
22
23
 
23
24
  self.class.pure(yield(value))
24
25
  end
25
26
 
26
- def bind(&block)
27
- return dup if left? || !block
27
+ def bind
28
+ raise UseError.new("#bind requires a block") unless block_given?
29
+ return dup if left?
28
30
 
29
- self.class.instance_exec(value, &block)
31
+ yield value
30
32
  end
31
33
 
32
34
  def left?
@@ -37,7 +39,12 @@ module TAlgebra
37
39
  is == RIGHT
38
40
  end
39
41
 
42
+ def from_either!
43
+ from_either { |e| raise UnsafeError.new("#from_either! exception. #{e}") }
44
+ end
45
+
40
46
  def from_either
47
+ raise UseError.new("#from_either called without block") unless block_given?
41
48
  return yield(value) if left?
42
49
  value
43
50
  end
@@ -0,0 +1,9 @@
1
+ module TAlgebra
2
+ module Monad
3
+ class UseError < StandardError
4
+ end
5
+
6
+ class UnsafeError < StandardError
7
+ end
8
+ end
9
+ end
@@ -19,6 +19,12 @@ module TAlgebra
19
19
  def to_maybe(value_or_nil)
20
20
  value_or_nil.nil? ? nothing : pure(value_or_nil)
21
21
  end
22
+
23
+ # def run_bind(ma, &block)
24
+ # # raise "Yield blocks must return instances of #{self}. Got #{ma.class}" unless [Parser, Parser::Optional].include?(ma.class)
25
+ #
26
+ # ma.bind(&block)
27
+ # end
22
28
  end
23
29
 
24
30
  def fmap(&block)
@@ -39,11 +45,24 @@ module TAlgebra
39
45
  is == JUST
40
46
  end
41
47
 
48
+ def from_maybe!
49
+ from_maybe { |e| raise UnsafeError.new("#from_maybe! exception. #{e}") }
50
+ end
51
+
42
52
  def from_maybe
53
+ raise UseError.new("#from_maybe called without block") unless block_given?
43
54
  return yield if nothing?
44
55
  value
45
56
  end
46
57
 
58
+ def fetch(key)
59
+ bind do |o|
60
+ self.class.to_maybe(
61
+ o.respond_to?(:[]) ? o[key] : o.send(key)
62
+ )
63
+ end
64
+ end
65
+
47
66
  def ==(other)
48
67
  to_obj == other.to_obj
49
68
  end
@@ -10,32 +10,44 @@ module TAlgebra
10
10
 
11
11
  class << self
12
12
  def failure(msg, name = nil)
13
- left(msg).with_name(name)
13
+ new(is: Either::LEFT, value: msg, name: name)
14
14
  end
15
15
 
16
16
  def parse(val, name = nil)
17
- right(val).with_name(name)
17
+ new(is: Either::RIGHT, value: val, name: name)
18
18
  end
19
19
 
20
20
  def fetch(o, key)
21
- parser = parse(o.respond_to?(:[]) ? o[key] : o.send(key))
22
- parser.with_name(key).optional
21
+ parse(o).fetch(key)
23
22
  end
24
23
 
25
24
  def fetch!(o, key)
26
- parser = parse(o.respond_to?(:[]) ? o[key] : o.send(key))
27
- parser.with_name(key).required
25
+ parse(o).fetch!(key)
26
+ end
27
+
28
+ def run_bind(ma, &block)
29
+ raise "Yield blocks must return instances of #{self}. Got #{ma.class}" unless [Parser, Parser::Optional].include?(ma.class)
30
+
31
+ ma.as_parser.bind(&block)
28
32
  end
29
33
  end
30
34
 
35
+ alias_method :valid?, :right?
36
+ alias_method :failure?, :left?
37
+
31
38
  attr_reader :name
32
39
  def with_name(name)
33
40
  @name = name
34
41
  self
35
42
  end
36
43
 
37
- alias_method :valid?, :right?
38
- alias_method :failure?, :left?
44
+ def fetch(key)
45
+ with_name(key).fmap { |o| o.respond_to?(:[]) ? o[key] : o.send(key) }.optional
46
+ end
47
+
48
+ def fetch!(key)
49
+ with_name(key).fmap { |o| o.respond_to?(:[]) ? o[key] : o.send(key) }.required
50
+ end
39
51
 
40
52
  def fmap
41
53
  super.with_name(name)
@@ -57,7 +69,7 @@ module TAlgebra
57
69
 
58
70
  def validate(msg = "Invalid")
59
71
  n = name
60
- bind { |val| yield(val) ? parse(val, n) : failure(msg, n) }
72
+ bind { |val| yield(val) ? Parser.parse(val, n) : Parser.failure(msg, n) }
61
73
  end
62
74
 
63
75
  def extract_parsed(&block)
@@ -65,6 +77,10 @@ module TAlgebra
65
77
  from_either(&block)
66
78
  end
67
79
 
80
+ def extract_parsed!
81
+ extract_parsed { |e| raise UnsafeError.new("#extract_parsed! exception. #{e}") }
82
+ end
83
+
68
84
  def required
69
85
  validate("Is required") { |v| !v.nil? }
70
86
  end
@@ -91,6 +107,10 @@ module TAlgebra
91
107
  end
92
108
  end
93
109
 
110
+ def as_parser
111
+ instance_of?(Parser::Optional) ? Parser.new(is: is, value: value, name: name) : self
112
+ end
113
+
94
114
  private
95
115
 
96
116
  def dup
@@ -17,10 +17,23 @@ module TAlgebra
17
17
  end
18
18
 
19
19
  def run(&block)
20
- e = Enumerator.new { |y| instance_exec(LazyYielder.new(y), &block) }
20
+ block_self = block.binding.receiver
21
+
22
+ self_class = self
23
+ block_self.define_singleton_method(:method_missing) do |m, *args, &block|
24
+ self_class.send(m, *args, &block)
25
+ end
26
+
27
+ e = Enumerator.new { |y| block_self.instance_exec(LazyYielder.new(y), &block) }
28
+
21
29
  run_recursive(e, [])
22
30
  end
23
31
 
32
+ def run_bind(ma, &block)
33
+ raise "Yield blocks must return instances of #{self}" unless ma.instance_of?(self)
34
+ ma.bind(&block)
35
+ end
36
+
24
37
  def lift_a2(ma, mb, &block)
25
38
  ma.bind do |a|
26
39
  mb.bind do |b|
@@ -40,9 +53,10 @@ module TAlgebra
40
53
  end
41
54
 
42
55
  if is_complete(enum)
43
- pure(value(enum))
56
+ val = value(enum)
57
+ val.is_a?(self.class) ? val : pure(val)
44
58
  else
45
- enum.next.call.bind do |a|
59
+ run_bind(enum.next.call) do |a|
46
60
  run_recursive(enum, historical_values + [a])
47
61
  end
48
62
  end
@@ -1,3 +1,3 @@
1
1
  module TAlgebra
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/t_algebra.rb CHANGED
@@ -2,6 +2,7 @@ require_relative "t_algebra/version"
2
2
  require_relative "t_algebra/functor"
3
3
  require_relative "t_algebra/applicative"
4
4
  require_relative "t_algebra/monad"
5
+ require_relative "t_algebra/monad/errors"
5
6
  require_relative "t_algebra/monad/maybe"
6
7
  require_relative "t_algebra/monad/either"
7
8
  require_relative "t_algebra/monad/list"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t_algebra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - aaron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-06 00:00:00.000000000 Z
11
+ date: 2021-12-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -33,6 +33,7 @@ files:
33
33
  - lib/t_algebra/functor.rb
34
34
  - lib/t_algebra/monad.rb
35
35
  - lib/t_algebra/monad/either.rb
36
+ - lib/t_algebra/monad/errors.rb
36
37
  - lib/t_algebra/monad/list.rb
37
38
  - lib/t_algebra/monad/maybe.rb
38
39
  - lib/t_algebra/monad/parser.rb