adt 0.0.5 → 0.0.6
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.
- data/lib/adt.rb +24 -8
- metadata +2 -2
data/lib/adt.rb
CHANGED
@@ -29,7 +29,7 @@ module ADT
|
|
29
29
|
# end
|
30
30
|
# end
|
31
31
|
#
|
32
|
-
# This will
|
32
|
+
# This will provide 2 core pieces of functionality.
|
33
33
|
#
|
34
34
|
# 1. Constructors, as class methods, named the same as the case, and expecting
|
35
35
|
# parameters as per the symbol arguments provided in the `cases` block.
|
@@ -79,9 +79,9 @@ module ADT
|
|
79
79
|
dsl.__instance_eval(&definitions)
|
80
80
|
|
81
81
|
cases = dsl._church_cases
|
82
|
-
num_cases =
|
83
|
-
case_names =
|
84
|
-
is_enumeration =
|
82
|
+
num_cases = cases.length
|
83
|
+
case_names = cases.map { |x| x[0] }
|
84
|
+
is_enumeration = cases.all?{ |(_, args)| args.count == 0 }
|
85
85
|
|
86
86
|
# creates procs with a certain arg count. body should use #{prefix}N to access arguments. The result should be
|
87
87
|
# eval'ed at the call site
|
@@ -105,10 +105,13 @@ module ADT
|
|
105
105
|
end
|
106
106
|
|
107
107
|
# If we're inside a named class, then set up an alias to fold
|
108
|
-
|
108
|
+
fold_synonym = StringHelp.underscore(name.split('::').last)
|
109
|
+
if fold_synonym && fold_synonym.length > 0 then
|
110
|
+
define_method(fold_synonym) do |*args| fold(*args) end
|
111
|
+
end
|
109
112
|
|
110
113
|
# The Constructors
|
111
|
-
|
114
|
+
cases.each_with_index do |(name, case_args), index|
|
112
115
|
constructor = proc { |*args| self.new(&eval(proc_create[num_cases, "a", "a#{index+1}.call(*args)"])) }
|
113
116
|
if case_args.size > 0 then
|
114
117
|
singleton_class.send(:define_method, name, &constructor)
|
@@ -122,11 +125,24 @@ module ADT
|
|
122
125
|
end
|
123
126
|
end
|
124
127
|
|
128
|
+
# Getter methods for common accessors
|
129
|
+
all_arg_names = cases.map { |(_, args)| args }.flatten
|
130
|
+
all_arg_names.each do |arg|
|
131
|
+
case_positions = cases.map { |(_, args)| args.index(arg) && [args.index(arg), args.count] }
|
132
|
+
if case_positions.all?
|
133
|
+
define_method(arg) do
|
134
|
+
fold(*case_positions.map { |(position, count)|
|
135
|
+
eval(proc_create[count, "a", "a#{position+1}" ])
|
136
|
+
})
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
125
141
|
# Case info methods
|
126
142
|
# Indexing is 1-based
|
127
143
|
define_method(:case_index) do fold(*(1..case_names.length).to_a.map { |i| proc { i } }) end
|
128
144
|
define_method(:case_name) do fold(*case_names.map { |i| proc { i.to_s } }) end
|
129
|
-
define_method(:case_arity) do fold(*
|
145
|
+
define_method(:case_arity) do fold(*cases.map { |(_, args)| proc { args.count } }) end
|
130
146
|
|
131
147
|
# Enumerations are defined as classes with cases that don't take arguments. A number of useful
|
132
148
|
# functions can be defined for these.
|
@@ -141,7 +157,7 @@ module ADT
|
|
141
157
|
|
142
158
|
# The usual object helpers
|
143
159
|
define_method(:inspect) do
|
144
|
-
"#<" + self.class.name + fold(*
|
160
|
+
"#<" + self.class.name + fold(*cases.map { |(cn, case_args)|
|
145
161
|
index = 0
|
146
162
|
bit = case_args.map { |ca|
|
147
163
|
index += 1
|