algebrick 0.5.0 → 0.6.0

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: df5b658188ef94835725f056d1872942a1f10fe3
4
- data.tar.gz: 5ac342bdfaaa354e8bf9575c25f1e06105170d18
3
+ metadata.gz: c10eb07ed10cdcc7fd01fda3b2dccf42786db60f
4
+ data.tar.gz: 72b0ecfd3d3ce1bc20c5683adeabb3d2b5915bfe
5
5
  SHA512:
6
- metadata.gz: 1207c3040b5d32c3d64cc47c29f9bccb83a979600cc9dc169d1424b6514297bc3c844bfa12e5d851663f08382019cdf948a85397e4363f21b4f835756c92235a
7
- data.tar.gz: af70a94f628feb94b59995adc5d6740cafdddf655a4c560f25e788c31f758138e21a6617abff047fc7d195176cf5357b7e9a65decb25916c0176d240b0f0eeb8
6
+ metadata.gz: 3d1dfceee22b44ed971953d37d3cb9e8e5caf03a2cdbda3be251c9e778f1a5e3ae7be41f2dfc17f3ea1ba7dc63f5a908ff481571957fe18b6267d4670f8d8be7
7
+ data.tar.gz: a0ed769069be44d01001a2657a07db0aa3ad3d184afb290d38bc2a82c0c72237737867f972380cc496689f4ee9169f1b3b6081eea7a6a792976c1a10b1621f7c
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/pitr-ch/algebrick.png?branch=master)](https://travis-ci.org/pitr-ch/algebrick)
4
4
 
5
- Typed structs on steroids based on algebraic types and pattern matching seamlessly integrating with standard Ruby features.
5
+ It's a gem providing **algebraic types** and **pattern matching** seamlessly integrates with standard features Ruby.
6
6
 
7
7
  - Documentation: <http://blog.pitr.ch/algebrick>
8
8
  - Source: <https://github.com/pitr-ch/algebrick>
@@ -10,11 +10,8 @@ Typed structs on steroids based on algebraic types and pattern matching seamless
10
10
 
11
11
  ## What is it good for?
12
12
 
13
- - Well defined data structures.
14
- - Actor messages see [new Actor implementation](http://rubydoc.info/gems/concurrent-ruby/Concurrent/Actress)
15
- in [concurrent-ruby](concurrent-ruby.com).
16
- - Describing message protocols in message-based cross-process communication.
17
- Algebraic types play nice with JSON de/serialization.
13
+ - Defining data structures.
14
+ - Algebraic types play nice with JSON serialization and deserialization. It is ideal for defining message-based cross-process communication.
18
15
  - and more...
19
16
 
20
17
  ## Quick example
data/README_FULL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Algebrick
2
2
 
3
- Typed structs on steroids based on algebraic types and pattern matching seamlessly integrating with standard Ruby features.
3
+ It's a gem providing **algebraic types** and **pattern matching** and seamlessly integrating with standard features of Ruby.
4
4
 
5
5
  - Documentation: <http://blog.pitr.ch/algebrick>
6
6
  - Source: <https://github.com/pitr-ch/algebrick>
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
data/doc/format.rb CHANGED
@@ -3,8 +3,9 @@ require 'bundler/setup'
3
3
  require 'pry'
4
4
  require 'pp'
5
5
 
6
+ root = File.dirname(File.expand_path(Process.argv0))
6
7
  input_paths = if ARGV.empty?
7
- Dir.glob("#{File.dirname(__FILE__)}/*.in.rb")
8
+ Dir.glob("#{root}/*.in.rb")
8
9
  else
9
10
  ARGV
10
11
  end.map { |p| File.expand_path p }
@@ -12,7 +13,7 @@ input_paths = if ARGV.empty?
12
13
  input_paths.each_with_index do |input_path, i|
13
14
 
14
15
  pid = fork do
15
- require_relative 'init.rb'
16
+ require File.join(root, 'init.rb')
16
17
 
17
18
  begin
18
19
  output_path = input_path.gsub /\.in\.rb$/, '.out.rb'
data/doc/json.out.rb CHANGED
@@ -20,7 +20,7 @@ require 'algebrick/serializer' # => true
20
20
  require 'multi_json' # => true
21
21
 
22
22
  # Prepare a message for sending.
23
- serializer = Algebrick::Serializer.new # => #<Algebrick::Serializer:0x007fab42bdf6d8>
23
+ serializer = Algebrick::Serializer.new # => #<Algebrick::Serializer:0x007fafcc96f6a8>
24
24
  request = CreateUser[User['root', 'lajDh4']]
25
25
  # => CreateUser[User[login: root, password: lajDh4]]
26
26
  raw_request = MultiJson.dump serializer.dump(request)
@@ -107,6 +107,34 @@ match BTree[0, Empty, BTree[1, Empty, Empty]],
107
107
  { left: left, value: value, right: right }
108
108
  end)
109
109
 
110
+ # It also supports matching against Ruby Arrays
111
+ Array.() === []
112
+ Array.() === [1]
113
+ Array.(*any) === []
114
+ Array.(*any) === [1]
115
+ Array.(*any) === [1, 2]
116
+ Array.(1, *any) === []
117
+ Array.(1, *any) === [1]
118
+ Array.(1, *any) === [1, 2]
119
+
120
+ match [],
121
+ on(~Array.to_m) { |v| v }
122
+ match [],
123
+ on(~Array.()) { |v| v }
124
+ match [1, 2],
125
+ on(~Array.(*any)) { |v| v }
126
+ match [1, 2],
127
+ on(~Array.(*any)) { |(v, _)| v }
128
+ match [1, 2, 3],
129
+ on(Array.(any, *~any)) { |v| v }
130
+ match [:first, 1, 2, 3],
131
+ on(Array.(:first, ~any, *any)) { |v| v }
132
+ match [:+, 1, 2, :foo, :bar],
133
+ (on Array.(:+, ~Integer.to_m, ~Integer.to_m, *~any) do |int1, int2, rest|
134
+ { sum: int1 + int2, rest: rest }
135
+ end)
136
+
137
+
110
138
  # There is also a more funky syntax for matching
111
139
  # using #>, #>> and Ruby 1.9 syntax for lambdas `-> {}`.
112
140
  match Leaf[1],
@@ -113,6 +113,34 @@ match BTree[0, Empty, BTree[1, Empty, Empty]],
113
113
  { left: left, value: value, right: right }
114
114
  end) # => {:left=>nil, :value=>0, :right=>1}
115
115
 
116
+ # It also supports matching against Ruby Arrays
117
+ Array.() === [] # => true
118
+ Array.() === [1] # => false
119
+ Array.(*any) === [] # => true
120
+ Array.(*any) === [1] # => true
121
+ Array.(*any) === [1, 2] # => true
122
+ Array.(1, *any) === [] # => false
123
+ Array.(1, *any) === [1] # => true
124
+ Array.(1, *any) === [1, 2] # => true
125
+
126
+ match [],
127
+ on(~Array.to_m) { |v| v } # => []
128
+ match [],
129
+ on(~Array.()) { |v| v } # => []
130
+ match [1, 2],
131
+ on(~Array.(*any)) { |v| v } # => [1, 2]
132
+ match [1, 2],
133
+ on(~Array.(*any)) { |(v, _)| v } # => 1
134
+ match [1, 2, 3],
135
+ on(Array.(any, *~any)) { |v| v } # => [2, 3]
136
+ match [:first, 1, 2, 3],
137
+ on(Array.(:first, ~any, *any)) { |v| v } # => 1
138
+ match [:+, 1, 2, :foo, :bar],
139
+ (on Array.(:+, ~Integer.to_m, ~Integer.to_m, *~any) do |int1, int2, rest|
140
+ { sum: int1 + int2, rest: rest }
141
+ end) # => {:sum=>3, :rest=>[:foo, :bar]}
142
+
143
+
116
144
  # There is also a more funky syntax for matching
117
145
  # using #>, #>> and Ruby 1.9 syntax for lambdas `-> {}`.
118
146
  match Leaf[1],
@@ -34,11 +34,13 @@ module Algebrick
34
34
 
35
35
  alias_method :>>, :>
36
36
 
37
- def ~
37
+ def assign!
38
38
  @assign = true
39
39
  self
40
40
  end
41
41
 
42
+ alias_method :~, :assign!
43
+
42
44
  def &(matcher)
43
45
  And.new self, matcher
44
46
  end
@@ -55,6 +57,10 @@ module Algebrick
55
57
  @assign
56
58
  end
57
59
 
60
+ def assigned?
61
+ !!@value
62
+ end
63
+
58
64
  def matched?
59
65
  @matched
60
66
  end
@@ -27,6 +27,15 @@ module Algebrick
27
27
  other.kind_of? self.class
28
28
  end
29
29
 
30
+ # transforms *any to many
31
+ def to_a
32
+ if assigned?
33
+ super
34
+ else
35
+ [Matchers::Many.new.tap { |m| m.assign! if assign? }]
36
+ end
37
+ end
38
+
30
39
  protected
31
40
 
32
41
  def matching?(other)
@@ -24,6 +24,7 @@ module Algebrick
24
24
  def initialize(*matchers)
25
25
  super()
26
26
  @matchers = matchers
27
+ raise ArgumentError, 'many can be only last' if @matchers[0..-2].any? { |v| v.is_a?(Many) }
27
28
  end
28
29
 
29
30
  def children
@@ -39,12 +40,21 @@ module Algebrick
39
40
  self.matchers == other.matchers
40
41
  end
41
42
 
43
+ def rest?
44
+ matchers.last.is_a?(Many)
45
+ end
46
+
42
47
  protected
43
48
 
44
49
  def matching?(other)
45
- other.kind_of? ::Array and
46
- matchers.size == other.size and
47
- matchers.each_with_index.all? { |m, i| m === other[i] }
50
+ return false unless other.kind_of? ::Array
51
+ if rest?
52
+ matchers[0..-2].zip(other).all? { |m, v| m === v } and
53
+ matchers.last === other[(matchers.size-1)..-1]
54
+ else
55
+ matchers.size == other.size and
56
+ matchers.zip(other).all? { |m, v| m === v }
57
+ end
48
58
  end
49
59
  end
50
60
 
@@ -53,5 +63,7 @@ module Algebrick
53
63
  Matchers::Array.new *matchers
54
64
  end
55
65
  end
66
+
67
+ # TODO consider: class Array; def ===(other); zip(other).all? {|m,v| m===v}; end; end
56
68
  end
57
69
  end
@@ -0,0 +1,37 @@
1
+ # Copyright 2013 Petr Chalupa <git+algebrick@pitr.ch>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Algebrick
16
+ module Matchers
17
+ class Many < Abstract
18
+ def children
19
+ []
20
+ end
21
+
22
+ def to_s
23
+ "*#{assign_to_s}any"
24
+ end
25
+
26
+ def ==(other)
27
+ other.kind_of? self.class
28
+ end
29
+
30
+ protected
31
+
32
+ def matching?(other)
33
+ true
34
+ end
35
+ end
36
+ end
37
+ end
@@ -21,6 +21,7 @@ module Algebrick
21
21
  require 'algebrick/matchers/or'
22
22
  require 'algebrick/matchers/not'
23
23
  require 'algebrick/matchers/any'
24
+ require 'algebrick/matchers/many'
24
25
  require 'algebrick/matchers/wrapper'
25
26
  require 'algebrick/matchers/array'
26
27
  require 'algebrick/matchers/product'
@@ -49,10 +49,10 @@ module Algebrick
49
49
  end
50
50
  end
51
51
 
52
- def self.empty
53
- LinkedListEmpty
52
+ def next?
53
+ self.next != EmptyLinkedList
54
54
  end
55
- end
55
+ end
56
56
  end
57
57
 
58
58
  include Types
data/lib/algebrick.rb CHANGED
@@ -21,6 +21,26 @@
21
21
  # TODO gemmify reclude
22
22
  # TODO gemmify typecheck
23
23
 
24
+ # TODO add default field values
25
+ # Person = Algebrick.type do
26
+ # fields! age: Integer,
27
+ # address: [Maybe[String], None]#,
28
+ # # address: Maybe[String] >> None
29
+ #
30
+ # field! :age, Integer
31
+ # field! :address, Maybe[String], None
32
+ # end
33
+ # Person[1]
34
+ # Person[1, Some['Praha']]
35
+
36
+ # TODO use benevolent deserializer to allow:
37
+ # Person[address: Address[name: 'asd']]
38
+ # Person[address: { name: 'asd' }]
39
+
40
+ # TODO maybe should behave as monad
41
+
42
+ # TODO anonymous types ? missing tests
43
+
24
44
 
25
45
  # Provides Algebraic types and pattern matching
26
46
  #
@@ -47,4 +67,5 @@ module Algebrick
47
67
  require 'algebrick/matchers'
48
68
  require 'algebrick/types'
49
69
 
70
+ # require 'algebrick/serializer'
50
71
  end
@@ -511,6 +511,8 @@ Named[
511
511
  ~Empty.to_m,
512
512
  any,
513
513
  ~any,
514
+ Array.(*any),
515
+ Array.(*~any),
514
516
  Leaf.(any),
515
517
  ~Leaf.(any),
516
518
  Node.(Leaf.(any), any),
@@ -555,6 +557,11 @@ Named[
555
557
  Array.(1) => [1],
556
558
  Array.(Empty, Leaf.(-> v { v > 0 })) => [Empty, Leaf[1]],
557
559
  Array.(TrueClass) => [true],
560
+ Array.(1, *any) => [1],
561
+ Array.(1, *any) => [1, 2],
562
+ Array.(1, *any) => [1, 2, 3],
563
+ Array.(*any) => [1],
564
+ Array.(*any) => [1, 2],
558
565
 
559
566
  BTree.(value: any) => BTree[1, Empty, Empty],
560
567
  BTree.(value: 1) => BTree[1, Empty, Empty],
@@ -635,6 +642,26 @@ Named[
635
642
  (on ~Leaf do |v|
636
643
  v.must_equal Leaf[1]
637
644
  end)
645
+
646
+ match [1, 2],
647
+ (on ~Array.(*any) do |(left, right)|
648
+ [left, right].must_equal [1, 2]
649
+ end)
650
+
651
+ match [1, 2],
652
+ (on ~Array.to_m do |(left, right)|
653
+ [left, right].must_equal [1, 2]
654
+ end)
655
+
656
+ match [1, 2],
657
+ (on ~Array.(*any) do |(left, right)|
658
+ [left, right].must_equal [1, 2]
659
+ end)
660
+
661
+ match [1, 2],
662
+ (on (Array.(*~any)) do |(left, right)|
663
+ [left, right].must_equal [1, 2]
664
+ end)
638
665
  end
639
666
 
640
667
  describe 'list' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algebrick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petr Chalupa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-18 00:00:00.000000000 Z
11
+ date: 2015-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -194,6 +194,7 @@ files:
194
194
  - lib/algebrick/matchers/any.rb
195
195
  - lib/algebrick/matchers/array.rb
196
196
  - lib/algebrick/matchers/atom.rb
197
+ - lib/algebrick/matchers/many.rb
197
198
  - lib/algebrick/matchers/not.rb
198
199
  - lib/algebrick/matchers/or.rb
199
200
  - lib/algebrick/matchers/product.rb