algebrick 0.5.0 → 0.6.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 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