ex_aequo_base 0.1.16 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ex_aequo/base/all.rb +2 -0
- data/lib/ex_aequo/base/fn/curry.rb +1 -1
- data/lib/ex_aequo/base/fn/helpers.rb +95 -30
- data/lib/ex_aequo/base/fn.rb +10 -2
- data/lib/ex_aequo/base/function/class_methods.rb +19 -0
- data/lib/ex_aequo/base/function/combinator_methods.rb +17 -0
- data/lib/ex_aequo/base/function.rb +42 -0
- data/lib/ex_aequo/base/import_all.rb +1 -0
- data/lib/ex_aequo/base/to_proc/unbound_method.rb +10 -0
- data/lib/ex_aequo/base/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b07e39f7fa5cfc7d8dbd8db59b023f831ec214e3d281bc55f5430afb815c9028
|
4
|
+
data.tar.gz: 2fe81797ea2ed2a385dda8b8637aa8618ee2a4ff75fff224120d7cc09f0b6038
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e011a5f3f439d0e2b8881885f6ac9bba59a7bdd8d7f0f65be791d24d3632ad644fb5d52b7c9addaa7ac57aab145cf08da2dd7ddc2aec72b4f25e9fbe81fe7773
|
7
|
+
data.tar.gz: c9ee6f3e9bb090efe94a8d17bdf82d1f5b97255376c542d57c2ac306efc4d52b4615abcb5ba3b77fd61c327134c82158e8e0d293b36a04b32d8e81edc1874b94
|
data/lib/ex_aequo/base/all.rb
CHANGED
@@ -3,11 +3,13 @@ require_relative 'colorize'
|
|
3
3
|
require_relative 'enumerable'
|
4
4
|
require_relative 'fn'
|
5
5
|
require_relative 'forwarder'
|
6
|
+
require_relative 'function'
|
6
7
|
require_relative 'kernel'
|
7
8
|
require_relative 'import_none'
|
8
9
|
require_relative 'open_struct'
|
9
10
|
require_relative 'regexp'
|
10
11
|
require_relative 'string'
|
12
|
+
require_relative 'to_proc'
|
11
13
|
# require_relative 'match_data'
|
12
14
|
# Colorize = ExAequo::Base::Colorize
|
13
15
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
@@ -3,52 +3,117 @@
|
|
3
3
|
module ExAequo
|
4
4
|
module Base
|
5
5
|
module Fn
|
6
|
-
|
6
|
+
PlaceholderClass = Class.new(BasicObject)
|
7
|
+
Placeholder = PlaceholderClass.new
|
7
8
|
|
8
9
|
module Helpers extend self
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def curry_send(*positionals, **keywords, &b)
|
11
|
+
-> (*args, **kwds, &blk) do
|
12
|
+
actual = _make_actual_params(positionals, args, keywords, kwds, arity: -1)
|
13
|
+
case actual
|
14
|
+
in {actual_args: [rcv, *actual_args], actual_kwds:, complete: true, **nil}
|
15
|
+
rcv.send(*actual_args, **actual_kwds, &(blk || b))
|
16
|
+
else
|
17
|
+
# This is a kludge to fix the simplecov missing branch _error_
|
18
|
+
actual in {actual_args: [_, *] => actual_args, actual_kwds:, complete: false, **nil}
|
19
|
+
curry_send(*actual_args, **actual_kwds, &(blk || b))
|
20
|
+
end
|
21
|
+
end
|
13
22
|
end
|
14
23
|
|
15
|
-
|
16
|
-
|
17
|
-
as = []
|
18
|
-
ks = {}
|
19
|
-
n = 0
|
24
|
+
def curry(*positionals, **keywords, &blk)
|
25
|
+
raise ArgumentError, "#{__method__} needs a block" unless blk
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
-> (*args, **kwds, &b) do
|
28
|
+
_make_actual_params(positionals, args, keywords, kwds, arity: blk.arity) => {actual_args:, actual_kwds:, complete:, **nil}
|
29
|
+
if complete
|
30
|
+
blk.(*actual_args, **actual_kwds, &b)
|
25
31
|
else
|
26
|
-
|
32
|
+
raise ArgumentError, "must not provide a block if function is still a partial application" if b
|
33
|
+
curry(*actual_args, **actual_kwds, &blk)
|
27
34
|
end
|
28
35
|
end
|
36
|
+
end
|
29
37
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
private
|
39
|
+
def _check_for_completeness(actual_args:, actual_kwds:, arity:)
|
40
|
+
if arity < 0
|
41
|
+
_check_for_min_completeness(actual_args:, actual_kwds:, arity: arity.abs.pred)
|
42
|
+
else
|
43
|
+
_check_for_exact_completeness(actual_args:, actual_kwds:, arity:)
|
35
44
|
end
|
36
|
-
as += Array(args[positionals.length-offset..])
|
37
|
-
[as, keywords.merge(ks).merge(kwds)]
|
38
45
|
end
|
39
46
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
47
|
+
def _check_for_exact_completeness(actual_args:, actual_kwds:, arity:)
|
48
|
+
arity = arity - 1 unless actual_kwds.empty?
|
49
|
+
_check_for_placeholders(actual_args:, actual_kwds:) => {complete:, size:, **nil}
|
50
|
+
raise ArgumentError, "too many arguments arity = #{arity} but #{size} provided" if size > arity
|
51
|
+
|
52
|
+
return {actual_args:, actual_kwds:, complete:} if size == arity
|
53
|
+
|
54
|
+
{
|
55
|
+
actual_args: actual_args + [Placeholder] * (arity - size),
|
56
|
+
actual_kwds:,
|
57
|
+
complete: false
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def _check_for_min_completeness(actual_args:, actual_kwds:, arity:)
|
62
|
+
_check_for_placeholders(actual_args:, actual_kwds:) => {complete:, size:, **nil}
|
63
|
+
return {actual_args:, actual_kwds:, complete:} if size >= arity
|
64
|
+
|
65
|
+
{
|
66
|
+
actual_args: actual_args + [Placeholder] * (arity - size),
|
67
|
+
actual_kwds:,
|
68
|
+
complete: false
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def _check_for_placeholders(actual_args:, actual_kwds:)
|
73
|
+
size = actual_args.size
|
74
|
+
needed_kwds = actual_kwds.values.count { it == Placeholder }
|
75
|
+
complete = actual_args.none? { it == Placeholder }
|
76
|
+
|
77
|
+
complete &&= needed_kwds.zero?
|
78
|
+
{complete:, size:}
|
79
|
+
end
|
80
|
+
|
81
|
+
def _make_actual_params(curried_args, current_args, curried_kwds, current_kwds, arity:)
|
82
|
+
_make_actual_args(curried_args, current_args) in actual_args, remaining_args
|
83
|
+
_make_actual_kwds(curried_kwds, current_kwds, remaining_args) in actual_kwds, remaining_args
|
84
|
+
|
85
|
+
actual_args += remaining_args
|
86
|
+
actual_kwds = curried_kwds.merge(actual_kwds).merge(current_kwds)
|
87
|
+
_check_for_completeness(actual_args:, actual_kwds:, arity:)
|
88
|
+
end
|
89
|
+
|
90
|
+
def _make_actual_args(curried_args, actual_args)
|
91
|
+
as = []
|
92
|
+
curried_args.each do
|
93
|
+
if actual_args.empty?
|
94
|
+
as << it
|
95
|
+
elsif it == Placeholder
|
96
|
+
as << actual_args.first
|
97
|
+
actual_args = actual_args.drop(1)
|
98
|
+
else
|
99
|
+
as << it
|
100
|
+
end
|
44
101
|
end
|
102
|
+
[as, actual_args]
|
45
103
|
end
|
46
104
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
105
|
+
def _make_actual_kwds(curried_kwds, actual_kwds, remaining_args)
|
106
|
+
ks = {}
|
107
|
+
curried_kwds.each do |k, v|
|
108
|
+
if v == Placeholder
|
109
|
+
case remaining_args
|
110
|
+
in [arg, *remaining_args]
|
111
|
+
ks[k] = arg
|
112
|
+
else
|
113
|
+
end
|
114
|
+
end
|
51
115
|
end
|
116
|
+
[ks, remaining_args]
|
52
117
|
end
|
53
118
|
end
|
54
119
|
end
|
data/lib/ex_aequo/base/fn.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'fn/curry'
|
3
4
|
require_relative 'to_proc'
|
4
5
|
module ExAequo
|
5
6
|
module Base
|
@@ -10,6 +11,11 @@ module ExAequo
|
|
10
11
|
'!' => _not,
|
11
12
|
}
|
12
13
|
|
14
|
+
def apply(fn_desc=nil, &blk)
|
15
|
+
fun = mk_fun_or(fn_desc, &blk)
|
16
|
+
-> (args) { fun.(*args) }
|
17
|
+
end
|
18
|
+
|
13
19
|
def mk_fun(fn_desc)
|
14
20
|
case fn_desc
|
15
21
|
in String
|
@@ -18,10 +24,12 @@ module ExAequo
|
|
18
24
|
-> { it.send(fn_desc) }
|
19
25
|
in Array
|
20
26
|
-> { it.send(*fn_desc) }
|
21
|
-
|
27
|
+
else
|
22
28
|
fn_desc.to_proc
|
23
29
|
end
|
24
|
-
|
30
|
+
rescue NoMethodError
|
31
|
+
-> { fn_desc === it }
|
32
|
+
# TODO: Allow for other fn_desc then Array and Symbolk
|
25
33
|
end
|
26
34
|
|
27
35
|
def mk_fun_or(fn_desc=nil, &blk)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ExAequo
|
4
|
+
module Base
|
5
|
+
class Function
|
6
|
+
module ClassMethods
|
7
|
+
def curried(*args, **kwds, &blk)
|
8
|
+
new(Fn.curry(*args, **kwds, &blk), level: 3)
|
9
|
+
end
|
10
|
+
|
11
|
+
def sending(*args, **kwds, &blk)
|
12
|
+
new(Fn.curry_send(*args, **kwds, &blk), level: 3)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
extend ClassMethods
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ExAequo
|
4
|
+
module Base
|
5
|
+
class Function
|
6
|
+
module CombinatorMethods
|
7
|
+
define_method :> do |other|
|
8
|
+
self.class.new(name: "(#{name} > #{other})") do |*args, **kwds, &blk|
|
9
|
+
other.(self.(*args, **kwds, &blk))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
include CombinatorMethods
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ex_aequo/base/fn'
|
4
|
+
require 'ex_aequo/base/function/class_methods'
|
5
|
+
require 'ex_aequo/base/function/combinator_methods'
|
6
|
+
module ExAequo
|
7
|
+
module Base
|
8
|
+
class Function
|
9
|
+
attr_reader :arity, :function, :name
|
10
|
+
|
11
|
+
def call(*args, **kwds, &blk)
|
12
|
+
function.(*args, **kwds, &blk)
|
13
|
+
rescue StandardError => e
|
14
|
+
raise(e, e.message + " in #{name}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def named(name)
|
18
|
+
@name = name
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_proc = function
|
23
|
+
|
24
|
+
def to_s = name
|
25
|
+
|
26
|
+
private
|
27
|
+
def initialize(func_desc=nil, name: nil, level: 1, &blk)
|
28
|
+
raise ArgumentError, "must not provide function description and a blk" if func_desc && blk
|
29
|
+
raise ArgumentError, "must provide either a function description or a blk" unless func_desc || blk
|
30
|
+
@function = blk ? blk : Fn.mk_fun(func_desc)
|
31
|
+
@arity = function.arity
|
32
|
+
@level = level
|
33
|
+
@name = name || _mk_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def _mk_name
|
37
|
+
@name = caller[@level]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ex_aequo_base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Dober
|
@@ -62,6 +62,9 @@ files:
|
|
62
62
|
- lib/ex_aequo/base/fn/curry.rb
|
63
63
|
- lib/ex_aequo/base/fn/helpers.rb
|
64
64
|
- lib/ex_aequo/base/forwarder.rb
|
65
|
+
- lib/ex_aequo/base/function.rb
|
66
|
+
- lib/ex_aequo/base/function/class_methods.rb
|
67
|
+
- lib/ex_aequo/base/function/combinator_methods.rb
|
65
68
|
- lib/ex_aequo/base/import_all.rb
|
66
69
|
- lib/ex_aequo/base/import_none.rb
|
67
70
|
- lib/ex_aequo/base/kernel.rb
|
@@ -78,6 +81,7 @@ files:
|
|
78
81
|
- lib/ex_aequo/base/to_proc/regexp.rb
|
79
82
|
- lib/ex_aequo/base/to_proc/string.rb
|
80
83
|
- lib/ex_aequo/base/to_proc/true_class.rb
|
84
|
+
- lib/ex_aequo/base/to_proc/unbound_method.rb
|
81
85
|
- lib/ex_aequo/base/version.rb
|
82
86
|
homepage: https://codeberg.org/lab419/rb_ex_aequo_base
|
83
87
|
licenses:
|