algebrick 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: c59b78e81ddad7a8982de954309dba01ccc26db9
4
- data.tar.gz: 94cbecbb1b1bd1f3ca682fa0707439b7afcba7fc
3
+ metadata.gz: 986e5746d10e9a2e2edf3c25da212fff33719dee
4
+ data.tar.gz: a711d19897aa1c4085948aa21cace8a86ede5ef6
5
5
  SHA512:
6
- metadata.gz: aeff2d9b02f3f947f0019c9c915f37194a1c02bc4d20eef4f7365ad22c836c8b4158b10cfc0686f66e9a640bb0cb1dff0cc39c253328ee043926f6dfe9dc851e
7
- data.tar.gz: d225e46f414574b28ff8719639d1ce193fe12e86935d27a9faef0bcaed2c3003ee2eebaf5eb336bdaf5f697d3f3ab8d24bd84df1e98c69d3f2d3161950b87453
6
+ metadata.gz: 5c0264da1e050dab04f2238905fab10b253762c68bcaa3c80103a6c4366efb236c003c3b8ce06cba03b0a0a7913f63662bf9246181237215881c99c77856d14a
7
+ data.tar.gz: 52d55de9dd00eebb7b6e38959cbf8bae0add19090ff04213a58a053f30389ef313669c41831848d5bf942f6a11274e4c1729f21dbd3b77256d1f4b2c02cac1dc
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ## Algebrick
2
2
 
3
- Algebraic types and pattern matching for Ruby.
3
+ Is a small gem providing algebraic types and pattern matching on them for Ruby.
4
4
 
5
- - Documentation: http://blog.pitr.ch/algebrick
6
- - Source: https://github.com/pitr-ch/algebrick
7
- - Blog: http://blog.pitr.ch/blog/categories/algebrick/
5
+ - Documentation: <http://blog.pitr.ch/algebrick>
6
+ - Source: <https://github.com/pitr-ch/algebrick>
7
+ - Blog: <http://blog.pitr.ch/blog/categories/algebrick/>
data/README_FULL.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Is a small gem providing algebraic types and pattern matching on them for Ruby.
4
4
 
5
- - Documentation: {http://blog.pitr.ch/algebrick}
6
- - Source: {https://github.com/pitr-ch/algebrick}
7
- - Blog: {http://blog.pitr.ch}
5
+ - Documentation: <http://blog.pitr.ch/algebrick>
6
+ - Source: <https://github.com/pitr-ch/algebrick>
7
+ - Blog: <http://blog.pitr.ch/blog/categories/algebrick/>
8
8
 
9
9
  ## Quick example with Maybe type
10
10
 
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
data/lib/algebrick.rb CHANGED
@@ -13,6 +13,10 @@ end
13
13
 
14
14
  module Algebrick
15
15
 
16
+ def self.version
17
+ @version ||= Gem::Version.new File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
18
+ end
19
+
16
20
  module TypeCheck
17
21
  #def is_kind_of?(value, *types)
18
22
  # a_type_check :kind_of?, false, value, *types
@@ -22,9 +26,9 @@ module Algebrick
22
26
  a_type_check :kind_of?, true, value, *types
23
27
  end
24
28
 
25
- #def is_matching?(value, *types)
26
- # a_type_check :===, false, value, *types
27
- #end
29
+ def is_matching?(value, *types)
30
+ a_type_check :===, false, value, *types
31
+ end
28
32
 
29
33
  def is_matching!(value, *types)
30
34
  a_type_check :===, true, value, *types
@@ -43,8 +47,10 @@ module Algebrick
43
47
  raise ArgumentError
44
48
  end
45
49
  end
46
- raise TypeError, "value (#{value.class}) '#{value}' is not ##{which} any of #{types.join(', ')}" if bang && !ok
47
- value
50
+ bang && !ok and
51
+ raise TypeError,
52
+ "value (#{value.class}) '#{value}' is not ##{which} any of #{types.join(', ')}"
53
+ bang ? value : ok
48
54
  end
49
55
  end
50
56
 
@@ -83,7 +89,7 @@ module Algebrick
83
89
  cases.each do |matcher, block|
84
90
  return match_value matcher, block if matcher === value
85
91
  end
86
- raise "no match for #{value} by any of #{cases.map(&:first).join ', '}"
92
+ raise "no match for (#{value.class}) '#{value}' by any of #{cases.map(&:first).join ', '}"
87
93
  end
88
94
 
89
95
  private
@@ -307,6 +313,20 @@ module Algebrick
307
313
  self
308
314
  end
309
315
 
316
+ def add_field_method_accessor(field)
317
+ raise TypeError, 'no field names' unless @field_names
318
+ raise TypeError, "no field name #{field}" unless @field_names.include? field
319
+ define_method(field) { self[field] }
320
+ end
321
+
322
+ def add_field_method_accessors(*fields)
323
+ fields.each { |f| add_field_method_accessor f }
324
+ end
325
+
326
+ def add_all_field_method_accessors
327
+ add_field_method_accessors *@field_names
328
+ end
329
+
310
330
  protected
311
331
 
312
332
  def be_kind_of!(type)
@@ -336,7 +356,9 @@ module Algebrick
336
356
  if keys
337
357
  @field_names = keys
338
358
  keys.all? { |k| is_kind_of! k, Symbol }
339
- dict = @field_indexes = keys.each_with_index.inject({}) { |h, (k, i)| h.update k => i }
359
+ dict = @field_indexes =
360
+ Hash.new { |h, k| raise ArgumentError, "uknown field #{k.inspect}" }.
361
+ update keys.each_with_index.inject({}) { |h, (k, i)| h.update k => i }
340
362
  define_method(:[]) { |key| @fields[dict[key]] }
341
363
  end
342
364
 
@@ -551,6 +573,8 @@ module Algebrick
551
573
 
552
574
  alias_method :>>, :-
553
575
 
576
+ raise 'remove deprecation' if Algebrick.version >= Gem::Version.new('0.2')
577
+
554
578
  def +(block)
555
579
  warn 'a_matcher +-> {} is deprecated, it\'ll be removed in 0.2'
556
580
  self - block
@@ -678,7 +702,7 @@ module Algebrick
678
702
  end
679
703
  end
680
704
 
681
- class Not < Abstract # TODO
705
+ class Not < Abstract
682
706
  attr_reader :matcher
683
707
 
684
708
  def initialize(matcher)
@@ -1012,8 +1036,14 @@ module Algebrick
1012
1036
  end
1013
1037
  end
1014
1038
 
1015
- def type_def(&definition)
1016
- Environment.new(self, &definition).run
1039
+ def type_def(base = self, &definition)
1040
+ Environment.new(base, &definition).run
1017
1041
  end
1018
1042
  end
1043
+
1044
+ extend DSL
1045
+
1046
+ def self.type_def(base, &definition)
1047
+ super base, &definition
1048
+ end
1019
1049
  end
data/spec/algebrick.rb ADDED
@@ -0,0 +1,541 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'minitest/spec'
4
+ #require 'minitest/autorun'
5
+ require 'turn/autorun'
6
+
7
+ require 'pp'
8
+ require_relative '../lib/algebrick'
9
+ require 'pry'
10
+
11
+ class Module
12
+ def const_missing const
13
+ raise "no constant #{const.inspect} in #{self}"
14
+ end
15
+ end
16
+
17
+ Turn.config do |c|
18
+ # use one of output formats:
19
+ # :outline - turn's original case/test outline mode [default]
20
+ # :progress - indicates progress with progress bar
21
+ # :dotted - test/unit's traditional dot-progress mode
22
+ # :pretty - new pretty reporter
23
+ # :marshal - dump output as YAML (normal run mode only)
24
+ # :cue - interactive testing
25
+ c.format = :outline
26
+ # turn on invoke/execute tracing, enable full backtrace
27
+ #c.trace = true
28
+ # use humanized test names (works only with :outline format)
29
+ c.natural = true
30
+ end
31
+
32
+
33
+ describe 'AlgebrickTest' do
34
+ i_suck_and_my_tests_are_order_dependent!
35
+
36
+ #type_def do
37
+ # maybe === none | some(Object)
38
+
39
+ # message === success | failure
40
+ # sucess === int(Integer) | str(String)
41
+ # failure === error | str_error(String)
42
+
43
+ #user = user(String, address) do
44
+ # def name
45
+ # fields[0]
46
+ # end
47
+ #
48
+ # def address
49
+ # fields[1]
50
+ # end
51
+ #end
52
+ #
53
+ #psc = psc(String) do
54
+ # REG = /\d{5}/
55
+ #
56
+ # def initialize(*fields)
57
+ # raise TypeError unless fields[0] =~ REG
58
+ # end
59
+ #
60
+ # def schema
61
+ # super << { pattern: REG.to_s }
62
+ # end
63
+ #end
64
+ #
65
+ ## street, num, city
66
+ #address = address(street(String), street_number(Integer), city(String), psc)
67
+ #
68
+ #message1 === user
69
+ #
70
+ #User['pepa',
71
+ # Adress[
72
+ # Street['Stavebni'],
73
+ # StreetNumber[5],
74
+ # City['Brno']]]
75
+ #
76
+ #{ user: ['pepa',
77
+ # { address: [{ street: 'Stavebni' },
78
+ # { street_number: 5 }] }] }
79
+
80
+ #sucess === int(Integer) | str(String)
81
+ #failure === error | str_error(String)
82
+ #message === success | failure
83
+
84
+
85
+ #list === empty | list_item(Integer, list)
86
+ #end
87
+
88
+ #Empty = Algebrick::Atom.new
89
+ #Leaf = Algebrick::Product.new(Integer)
90
+ #Tree = Algebrick::Variant.allocate
91
+ #Node = Algebrick::Product.new(Tree, Tree)
92
+ #Tree.send :initialize, Empty, Leaf, Node do
93
+ # def a
94
+ # :a
95
+ # end
96
+ #end
97
+ #List = Algebrick::ProductVariant.allocate
98
+ #List.send :initialize, [Integer, List], [Empty, List]
99
+
100
+ extend Algebrick::DSL
101
+
102
+ type_def do
103
+ tree === empty | leaf(Integer) | node(tree, tree)
104
+ tree do
105
+ def a
106
+ :a
107
+ end
108
+
109
+ def depth
110
+ case self
111
+ when Empty
112
+ 0
113
+ when Leaf
114
+ 1
115
+ when Node
116
+ left, right = *self
117
+ 1 + [left.depth, right.depth].max
118
+ end
119
+ end
120
+
121
+ def each(&block)
122
+ return to_enum :each unless block
123
+ case self
124
+ when Empty
125
+ when Leaf
126
+ block.call self.value
127
+ when Node
128
+ left, right = *self
129
+ left.each &block
130
+ right.each &block
131
+ end
132
+ end
133
+
134
+ def sum
135
+ each.inject(0) { |sum, v| sum + v }
136
+ end
137
+ end
138
+
139
+ list === empty | list(Integer, list)
140
+ end
141
+
142
+ Empty = self::Empty
143
+ Node = self::Node
144
+ Leaf = self::Leaf
145
+ Tree = self::Tree
146
+ List = self::List
147
+
148
+ describe 'type definition' do
149
+ module Asd
150
+ Algebrick.type_def self do
151
+ b === c | d
152
+ end
153
+ end
154
+
155
+ it 'asd' do
156
+ assert Asd::B
157
+ end
158
+ end
159
+
160
+ describe 'type.to_s' do
161
+ it { Empty.to_s.must_equal 'Empty' }
162
+ it { Node.to_s.must_equal 'Node(Tree, Tree)' }
163
+ it { Leaf.to_s.must_equal 'Leaf(Integer)' }
164
+ it { Tree.to_s.must_equal 'Tree(Empty | Leaf | Node)' }
165
+ it { List.to_s.must_equal 'List(Empty | List(Integer, List))' }
166
+ end
167
+
168
+ describe 'atom' do
169
+ it { Empty.must_be_kind_of Algebrick::Type }
170
+ it { Empty.must_be_kind_of Algebrick::Value }
171
+ it { assert Empty.kind_of? Empty }
172
+
173
+ it { assert Empty == Empty }
174
+ it { assert Empty === Empty }
175
+ it { eval(Empty.to_s).must_equal Empty }
176
+ it { eval(Empty.inspect).must_equal Empty }
177
+
178
+ it { Empty.from_hash(Empty.to_hash).must_equal Empty }
179
+ end
180
+
181
+ describe 'product' do
182
+ it { Leaf[1].must_be_kind_of Algebrick::Value }
183
+ it { Leaf.must_be_kind_of Algebrick::Type }
184
+ it { Leaf[1].wont_be_kind_of Algebrick::Type }
185
+ it { Leaf.wont_be_kind_of Algebrick::Value }
186
+
187
+ it { assert Leaf[1] == Leaf[1] }
188
+ it { assert Leaf[1] != Leaf[0] }
189
+ it { assert Leaf === Leaf[1] }
190
+ it { assert Leaf[1].kind_of? Leaf }
191
+ it { eval(Leaf[1].to_s).must_equal Leaf[1] }
192
+ it { eval(Leaf[1].inspect).must_equal Leaf[1] }
193
+ it { eval(Node[Leaf[1], Empty].to_s).must_equal Node[Leaf[1], Empty] }
194
+ it { eval(Node[Leaf[1], Empty].inspect).must_equal Node[Leaf[1], Empty] }
195
+
196
+ it 'field assign' do
197
+ value = Leaf[1].value
198
+ value.must_equal 1
199
+
200
+ left, right = *Node[Empty, Leaf[1]]
201
+ left.must_equal Empty
202
+ right.must_equal Leaf[1]
203
+
204
+ lambda { Node[Empty, Empty].value }.must_raise NoMethodError
205
+ end
206
+
207
+ it { lambda { Leaf['a'] }.must_raise TypeError }
208
+ it { lambda { Leaf[nil] }.must_raise TypeError }
209
+ it { lambda { Node['a'] }.must_raise TypeError }
210
+ it { lambda { Node[Empty, nil] }.must_raise TypeError }
211
+
212
+ describe 'named field' do
213
+ type_def { named(a: Integer, b: Object) }
214
+ Named = self::Named
215
+ Named.add_all_field_method_accessors
216
+ it { -> { Named[:a, 1] }.must_raise TypeError }
217
+ it { Named[1, :a][:a].must_equal 1 }
218
+ it { Named[1, :a][:b].must_equal :a }
219
+ it { Named[a: 1, b: :a][:a].must_equal 1 }
220
+ it { Named[b: :a, a: 1][:a].must_equal 1 }
221
+ it { Named[a: 1, b: :a][:b].must_equal :a }
222
+ it { Named[a: 1, b: 2].to_s.must_equal 'Named[a: 1, b: 2]' }
223
+ it { Named[a: 1, b: 2].a.must_equal 1 }
224
+ it { Named[a: 1, b: 2].b.must_equal 2 }
225
+ end
226
+
227
+ it { Leaf.from_hash(Leaf[1].to_hash).must_equal Leaf[1] }
228
+ it { Named.from_hash(Named[1, :a].to_hash).must_equal Named[1, :a] }
229
+ it { Named[1, Leaf[1]].to_hash.must_equal 'Named' => { a: 1, b: { 'Leaf' => [1] } } }
230
+ it { Named.from_hash(Named[1, Leaf[1]].to_hash).must_equal Named[1, Leaf[1]] }
231
+
232
+ end
233
+
234
+ describe 'variant' do
235
+ it { Tree.must_be_kind_of Algebrick::Type }
236
+ it { Empty.must_be_kind_of Tree }
237
+ it { Empty.a.must_equal :a }
238
+ it { Leaf[1].must_be_kind_of Tree }
239
+ it { Leaf[1].a.must_equal :a }
240
+ it { Node[Empty, Empty].must_be_kind_of Tree }
241
+ #it { assert Empty.kind_of? List }
242
+
243
+ it { assert Tree === Empty }
244
+ it { assert Tree === Leaf[1] }
245
+
246
+ describe 'inherit behavior deep' do
247
+ type_def do
248
+ a === a1 | a2
249
+ a1 === b1 | b2
250
+ a do
251
+ def a
252
+ :a
253
+ end
254
+ end
255
+ end
256
+
257
+ it { self.class::B1.a.must_equal :a }
258
+ end
259
+
260
+ describe 'a klass as a variant' do
261
+ MaybeString = Algebrick::Variant.new Empty, String
262
+ it { 'a'.must_be_kind_of MaybeString }
263
+ end
264
+ end
265
+
266
+ describe 'product_variant' do
267
+ it { List[1, Empty].must_be_kind_of Algebrick::Value }
268
+ it { List.must_be_kind_of Algebrick::Type }
269
+
270
+ it { List[1, Empty].must_be_kind_of List }
271
+ it { List[1, List[1, Empty]].must_be_kind_of List }
272
+ it { Empty.must_be_kind_of List }
273
+
274
+ it { assert List[1, Empty] == List[1, Empty] }
275
+ it { assert List[1, Empty] != List[2, Empty] }
276
+ it { assert List === List[1, Empty] }
277
+ it { assert List === Empty }
278
+ it { assert List[1, Empty].kind_of? List }
279
+ end
280
+
281
+ describe '#depth' do
282
+ it do
283
+ tree = Node[Node[Empty, Leaf[1]], Leaf[1]]
284
+ tree.depth.must_equal 3
285
+ end
286
+ it do
287
+ tree = Node[Empty, Leaf[1]]
288
+ tree.depth.must_equal 2
289
+ end
290
+ it do
291
+ tree = Empty
292
+ tree.depth.must_equal 0
293
+ end
294
+ end
295
+
296
+ describe '#sum' do
297
+ it do
298
+ tree = Node[Node[Empty, Leaf[1]], Leaf[1]]
299
+ tree.sum.must_equal 2
300
+ end
301
+ end
302
+
303
+ describe 'maybe' do
304
+ type_def do
305
+ maybe === none | some(Object)
306
+ maybe do
307
+ def maybe(&block)
308
+ case self
309
+ when None
310
+ when Some
311
+ block.call self.value
312
+ end
313
+ end
314
+ end
315
+ end
316
+
317
+ None = self::None
318
+ Some = self::Some
319
+
320
+ it { refute None.maybe { true } }
321
+ it { assert Some[nil].maybe { true } }
322
+ end
323
+
324
+ extend Algebrick::Matching
325
+ include Algebrick::Matching
326
+
327
+ describe 'matchers' do
328
+ it 'assigns' do
329
+ m = ~Empty
330
+ m === 2
331
+ m.assigns.must_equal [nil]
332
+ m === Empty
333
+ m.assigns.must_equal [Empty]
334
+
335
+ m = ~String.to_m
336
+ m === 2
337
+ m.assigns.must_equal [nil]
338
+ m === 'a'
339
+ m.assigns.must_equal %w(a)
340
+
341
+ m = ~Leaf.(~any)
342
+ m === Leaf[5]
343
+ m.assigns.must_equal [Leaf[5], 5]
344
+ m === Leaf[3]
345
+ m.assigns.must_equal [Leaf[3], 3]
346
+ end
347
+
348
+ it 'assigns in case' do
349
+ case Leaf[5]
350
+ when m = ~Leaf.(~any)
351
+ m.assigns.must_equal [Leaf[5], 5]
352
+ m.assigns do |leaf, value|
353
+ leaf.must_equal Leaf[5]
354
+ value.must_equal 5
355
+ end
356
+ else
357
+ raise
358
+ end
359
+ end
360
+
361
+ describe 'match' do
362
+ it 'returns value from executed block' do
363
+ Algebrick.match(Empty, Empty.to_m.case { 1 }).must_equal 1
364
+ end
365
+
366
+ it 'passes assigned values' do
367
+ v = Algebrick.match Leaf[5],
368
+ Leaf.(~any).case { |value| value }
369
+ v.must_equal 5
370
+
371
+ v = Algebrick.match Leaf[5],
372
+ Leaf.(~any) => -> value { value }
373
+ v.must_equal 5
374
+ end
375
+
376
+ it 'raises when no match' do
377
+ -> { Algebrick.match Empty,
378
+ Leaf.(any).case {} }.must_raise RuntimeError
379
+ end
380
+
381
+ it 'does not pass any values when no matcher' do
382
+ Algebrick.match(Empty, Empty => -> *a { a }).must_equal []
383
+ end
384
+ end
385
+
386
+ describe '#to_s' do
387
+ [Empty.to_m,
388
+ # leaf(Object)
389
+ ~Leaf.(Integer),
390
+ ~Empty.to_m,
391
+ any,
392
+ ~any,
393
+ Leaf.(any),
394
+ ~Leaf.(any),
395
+ Node.(Leaf.(any), any),
396
+ ~Node.(Leaf.(any), any),
397
+ ~Leaf.(1) | Leaf.(~any),
398
+ ~Leaf.(1) & Leaf.(~any)
399
+ ].each do |matcher|
400
+ it matcher.to_s do
401
+ eval(matcher.to_s).must_equal matcher
402
+ end
403
+ end
404
+ end
405
+
406
+ { Empty.to_m => Empty,
407
+ any => Empty,
408
+ any => Leaf[1],
409
+
410
+ Empty => Empty,
411
+ Empty.to_m => Empty,
412
+
413
+ Leaf => Leaf[1],
414
+ Leaf.(any) => Leaf[5],
415
+ Leaf.(~any) => Leaf[5],
416
+
417
+ Node => Node[Empty, Empty],
418
+ Node.(any, any) => Node[Leaf[1], Empty],
419
+ Node.(Empty, any) => Node[Empty, Leaf[1]],
420
+ Node.(Leaf.(any), any) => Node[Leaf[1], Empty],
421
+ Node.(Leaf.(any), any) => Node[Leaf[1], Empty],
422
+
423
+ Tree.to_m => Node[Leaf[1], Empty],
424
+ Tree.to_m => Node[Leaf[1], Empty],
425
+ Node => Node[Leaf[1], Empty],
426
+
427
+ Tree & Leaf.(_) => Leaf[1],
428
+ Empty | Leaf.(_) => Leaf[1],
429
+ Empty | Leaf.(_) => Empty,
430
+ !Empty & Leaf.(_) => Leaf[1],
431
+ Empty & !Leaf.(_) => Empty,
432
+
433
+ Array.() => [],
434
+ Array.(1) => [1],
435
+ Array.(Empty, Leaf.(-> v { v > 0 })) => [Empty, Leaf[1]],
436
+ Array.(TrueClass) => [true],
437
+
438
+ }.each do |matcher, value|
439
+ it "#{matcher} === #{value}" do
440
+ assert matcher === value
441
+ end
442
+ end
443
+ end
444
+
445
+ it {
446
+ assert List.to_m === Empty
447
+ assert List === Empty
448
+ assert List.to_m === List[1, Empty]
449
+ assert List === List[1, Empty]
450
+ assert List.(1, _) === List[1, Empty]
451
+ refute List.(_, _) === Empty
452
+ }
453
+
454
+ describe 'and-or matching' do
455
+ it do
456
+ m = ~Leaf.(1) | ~Leaf.(~any)
457
+ assert m === Leaf[1]
458
+ m.assigns.must_equal [Leaf[1], nil, nil]
459
+ end
460
+ it do
461
+ m = ~Leaf.(1) | ~Leaf.(~any)
462
+ assert m === Leaf[2]
463
+ m.assigns.must_equal [nil, Leaf[2], 2]
464
+ end
465
+ it do
466
+ m = ~Leaf.(->(v) { v > 1 }) & Leaf.(~any)
467
+ assert m === Leaf[2]
468
+ m.assigns.must_equal [Leaf[2], 2]
469
+ end
470
+
471
+ end
472
+
473
+ describe 'equality' do
474
+ data = (0..1).map do
475
+ [Empty,
476
+ Leaf[1],
477
+ Node[Empty, Leaf[1]],
478
+ Node[Node[Empty, Leaf[1]], Leaf[1]]]
479
+ end
480
+ data[0].zip(data[1]).each do |tree1, tree2|
481
+ it "equals #{tree1}" do
482
+ refute tree1.object_id == tree2.object_id, [tree1.object_id, tree2.object_id] unless tree1 == Empty
483
+ assert tree1 == tree2
484
+ end
485
+ end
486
+ end
487
+
488
+ describe 'list' do
489
+ it { List.(any, any) === List[1, Empty] }
490
+ it { List.(any, List) === List[1, Empty] }
491
+ end
492
+
493
+ describe 'binary tree' do
494
+ type_def { b_tree === tip | b_node(Object, b_tree, b_tree) }
495
+ end
496
+
497
+ end
498
+
499
+
500
+ #require 'benchmark'
501
+ #
502
+ #include Algebrick
503
+ #
504
+ #class None < Atom
505
+ #end
506
+ #
507
+ #class Some < Product
508
+ # fields Object
509
+ #end
510
+ #
511
+ #Maybe = Variant.new do
512
+ # variants None, Some
513
+ #end
514
+ #count = 1000_000
515
+ #
516
+ #Benchmark.bmbm(10) do |b|
517
+ # b.report('nil') do
518
+ # count.times do
519
+ # v = [Object.new, nil].sample
520
+ # case v
521
+ # when Object
522
+ # true
523
+ # when nil
524
+ # false
525
+ # end
526
+ # end
527
+ # end
528
+ # b.report('Maybe') do
529
+ # count.times do
530
+ # v = [Some[Object.new], None].sample
531
+ # case v
532
+ # when Some
533
+ # true
534
+ # when Maybe
535
+ # false
536
+ # end
537
+ # end
538
+ # end
539
+ #
540
+ #
541
+ #end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algebrick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petr Chalupa
@@ -104,9 +104,11 @@ extra_rdoc_files:
104
104
  - README_FULL.md
105
105
  files:
106
106
  - lib/algebrick.rb
107
+ - VERSION
107
108
  - MIT-LICENSE
108
109
  - README.md
109
110
  - README_FULL.md
111
+ - spec/algebrick.rb
110
112
  homepage: https://github.com/pitr-ch/algebrick
111
113
  licenses:
112
114
  - MIT
@@ -131,5 +133,6 @@ rubygems_version: 2.0.0
131
133
  signing_key:
132
134
  specification_version: 4
133
135
  summary: Algebraic types and pattern matching for Ruby
134
- test_files: []
136
+ test_files:
137
+ - spec/algebrick.rb
135
138
  has_rdoc: