obfusk 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: ab52e4ba4fbe81a4bd33c4a117a3c07affd52145
4
- data.tar.gz: c66dbc2b709774495e2e62eb7caa602a62d44e85
3
+ metadata.gz: 4c4bd6bb10352b9c18b779e647b5acfd1c3877db
4
+ data.tar.gz: c6f6309c765f5c519e155286323bbbb9d82590ff
5
5
  SHA512:
6
- metadata.gz: fd8d2b17d29df81221aea8c51ccbe9e868e23092ae0a85964b912f18493152103192ac36f3caf03b13865783960dd747cc38f2f1b04e99ce82ce4a4ab1f20399
7
- data.tar.gz: 2a2dfba314ab304371df55b379e898eb00de023c2141d6e335df8f963463f4929289279a40cc4176c56446b980b8a4226d213a5b1c51b3480d30fa3a496471f6
6
+ metadata.gz: a4dbae8abf373e372b28bbba4b913e2afcc6045c0f4a2480dc8164fabcdbeaee09685530075828bf2b35de45ba62145c7f7b5f2d0769d5141edbd2cbf4b611e4
7
+ data.tar.gz: d404720017b40471a4c8abf19ccf6e2ee5261fbe1f43d3763e88992d027b5af3148911a0f6a92ec171917c293087aa33276e16d4ad66bcef68bb53dd55e1152f
data/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  File : README.md
4
4
  Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- Date : 2014-06-16
5
+ Date : 2014-06-18
6
6
 
7
7
  Copyright : Copyright (C) 2014 Felix C. Stegerman
8
- Version : v0.1.1
8
+ Version : v0.1.2
9
9
 
10
10
  []: }}}1
11
11
 
@@ -27,10 +27,23 @@ class Foo
27
27
  constructor :Baz, :value
28
28
  end
29
29
 
30
- x = Foo.Bar()
30
+ x = Foo.Bar
31
31
  y = Foo.Baz 99
32
32
 
33
- puts y.value # => 99
33
+ y.value # => 99
34
+
35
+ x.match Bar: -> (_) { "it's a bar!" },
36
+ Baz: -> (z) { "it's a baz with value: #{z.value}" }
37
+ # => "it's a bar!"
38
+ ```
39
+
40
+ ```ruby
41
+ require 'obfusk/atom'
42
+
43
+ x = Obfusk.atom 42
44
+ x._ # => 42
45
+ 10.times { x.swap! { |v| v + 1 } }
46
+ x._ # => 53
34
47
  ```
35
48
 
36
49
  ```ruby
@@ -67,7 +80,7 @@ require 'obfusk/monad'
67
80
 
68
81
  class Foo
69
82
  include Obfusk::Monad
70
- def self.return(x)
83
+ def self.mreturn(x)
71
84
  # ...
72
85
  end
73
86
  def self.bind_pass(m, &b)
@@ -78,20 +91,21 @@ end
78
91
  f = -> x { '...' }
79
92
  g = -> y { '...' }
80
93
 
81
- Foo.pipeline Foo.new('...'), f, g
94
+ Foo.new('...').pipeline f, g
82
95
  ```
83
96
 
84
97
  ```ruby
85
98
  require 'obfusk/monads'
99
+ ms = Obfusk::Monads
86
100
 
87
- x = Obfusk.Nothing
88
- y = Obfusk.Just 42
101
+ x = ms.Nothing
102
+ y = ms.Just 42
89
103
 
90
104
  x.bind(y)
91
- # => Obfusk.Nothing
105
+ # => ms.Nothing
92
106
 
93
- Obfusk.Left "oops"
94
- Obfusk.Right 37
107
+ ms.Left "oops"
108
+ ms.Right 37
95
109
  ```
96
110
 
97
111
  ...
data/lib/obfusk/adt.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # File : obfusk/adt.rb
4
4
  # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- # Date : 2014-06-15
5
+ # Date : 2014-06-17
6
6
  #
7
7
  # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
8
  # Licence : LGPLv3+
@@ -17,6 +17,8 @@ module Obfusk
17
17
 
18
18
  # Algebraic Data Type
19
19
  module ADT
20
+ module Constructor; end
21
+
20
22
  include Comparable
21
23
 
22
24
  def self.included(base)
@@ -30,13 +32,24 @@ module Obfusk
30
32
  end
31
33
 
32
34
  module ClassMethods
35
+ # record constructor; call with name of constructor and hash of
36
+ # keys to values
37
+ def new(*a, &b)
38
+ ancestors.include?(::Obfusk::ADT::Constructor) ? super : _new(*a, &b)
39
+ end
40
+
41
+ def _new(ctor, data = {}, &b)
42
+ c = constructors[ctor]
43
+ c[:method].call *data.values_at(*c[:keys]), &b
44
+ end
45
+
33
46
  # duplicate constructors for subclasses
34
47
  def inherited(subclass)
35
48
  return if ::Obfusk::ADT_Meta__[:inheriting].last
36
49
  ctors = constructors
37
50
  subclass.class_eval do
38
51
  ctors.each_pair do |k,v|
39
- constructor v[:ctor_name], *v[:ctor_keys], &v[:ctor_block]
52
+ constructor v[:name], *v[:keys], &v[:block]
40
53
  end
41
54
  end
42
55
  end
@@ -56,17 +69,17 @@ module Obfusk
56
69
  end
57
70
  end
58
71
  ctor.class_eval do
59
- attr_accessor :ctor, :ctor_name, :ctor_keys
60
- keys_.each { |k| define_method(k) { @data[k] } }
72
+ include ::Obfusk::ADT::Constructor
73
+ keys_.each { |k| define_method(k) { __adt_data__[k] } }
61
74
  define_method(:initialize) do |guard, ctor, *values, &f|
62
75
  raise ArgumentError, 'for internal use only!' \
63
76
  unless guard == :for_internal_use_only
64
77
  if !b && (k = keys_.length) != (v = values.length)
65
78
  raise ArgumentError, "wrong number of arguments (#{v} for #{k})"
66
79
  end
67
- data = Hash[keys_.zip values]
80
+ data = Hash[keys_.zip values].freeze
68
81
  @ctor = ctor ; @ctor_name = name_ ; @ctor_keys = keys_
69
- @data = b ? b[self, data, values, f] : data
82
+ @data = b ? b[self, data, values, f].freeze : data
70
83
  end
71
84
  end
72
85
  class_eval do
@@ -81,8 +94,8 @@ module Obfusk
81
94
  define_method(name_) { |*values,&b| f[values,b] }
82
95
  end
83
96
  constructors[name_] = {
84
- ctor: ctor, method: method(name_),
85
- ctor_name: name_, ctor_keys: keys_, ctor_block: b
97
+ ctor: ctor, method: method(name_), name: name_,
98
+ keys: keys_, block: b
86
99
  }
87
100
  end
88
101
  name_
@@ -95,11 +108,11 @@ module Obfusk
95
108
  end
96
109
 
97
110
  # import the constructors into another namespace
98
- def import_constructors(scope)
111
+ def import_constructors(scope, const = true)
99
112
  constructors.each_pair do |k,v|
100
113
  m = method k
101
114
  scope.define_singleton_method(k) { |*a,&b| m[*a,&b] }
102
- scope.const_set k, v[:ctor]
115
+ scope.const_set k, v[:ctor] if const
103
116
  end
104
117
  end
105
118
 
@@ -113,8 +126,27 @@ module Obfusk
113
126
  end
114
127
  end
115
128
 
129
+ # clone
130
+ def clone(merge_data = {})
131
+ merge_data.empty? ? self :
132
+ self.class.superclass.new(__adt_ctor_name__,
133
+ __adt_data__.merge(merge_data))
134
+ end
135
+
136
+ def __adt_ctor__
137
+ @ctor
138
+ end
139
+
140
+ def __adt_ctor_name__
141
+ @ctor_name
142
+ end
143
+
144
+ def __adt_ctor_keys__
145
+ @ctor_keys
146
+ end
147
+
116
148
  # the data
117
- def _data
149
+ def __adt_data__
118
150
  @data
119
151
  end
120
152
 
@@ -122,7 +154,7 @@ module Obfusk
122
154
  def ==(rhs)
123
155
  rhs.is_a?(::Obfusk::ADT) &&
124
156
  self.class.superclass == rhs.class.superclass &&
125
- ctor == rhs.ctor && _eq_data(rhs)
157
+ __adt_ctor__ == rhs.__adt_ctor__ && _eq_data(rhs)
126
158
  end
127
159
 
128
160
  # equal and of the same type?
@@ -135,16 +167,18 @@ module Obfusk
135
167
  return nil unless rhs.is_a?(::Obfusk::ADT) &&
136
168
  self.class.superclass == rhs.class.superclass
137
169
  k = self.class.superclass.constructors.keys
138
- ctor != rhs.ctor ? k.index(ctor_name) <=> k.index(rhs.ctor_name) :
170
+ __adt_ctor__ != rhs.__adt_ctor__ ?
171
+ k.index(__adt_ctor_name__) <=> k.index(rhs.__adt_ctor_name__) :
139
172
  _compare_data(rhs)
140
173
  end
141
174
 
142
175
  def _eq_data(rhs)
143
- _data == rhs._data
176
+ __adt_data__ == rhs.__adt_data__
144
177
  end
145
178
 
146
179
  def _compare_data(rhs)
147
- _data.values_at(*ctor_keys) <=> rhs._data.values_at(*ctor_keys)
180
+ __adt_data__.values_at(*__adt_ctor_keys__) <=>
181
+ rhs.__adt_data__.values_at(*__adt_ctor_keys__)
148
182
  end
149
183
 
150
184
  # pattern matching
@@ -154,12 +188,13 @@ module Obfusk
154
188
  raise ArgumentError,
155
189
  "constructors do not match (#{ok} for #{ck})"
156
190
  end
157
- opts[ctor_name][self]
191
+ opts[__adt_ctor_name__][self]
158
192
  end
159
193
 
160
194
  # to string
161
195
  def to_s
162
- "#<#{self.class.superclass.name || '#ADT'}.#{ctor_name}: #{@data}>"
196
+ n = self.class.superclass.name || '#ADT'
197
+ "#<#{n}.#{__adt_ctor_name__}: #{__adt_data__}>"
163
198
  end
164
199
 
165
200
  # to string
@@ -0,0 +1,44 @@
1
+ # -- ; {{{1
2
+ #
3
+ # File : obfusk/atom.rb
4
+ # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
+ # Date : 2014-06-16
6
+ #
7
+ # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
+ # Licence : LGPLv3+
9
+ #
10
+ # -- ; }}}1
11
+
12
+ require 'thread'
13
+
14
+ module Obfusk
15
+ class Atom
16
+ attr_reader :value
17
+ alias :_ :value
18
+ alias :deref :value
19
+
20
+ # new Atom with value
21
+ def initialize(value)
22
+ @mutex = Mutex.new
23
+ @value = value
24
+ end
25
+
26
+ # calls block with value; uses a mutex to synchronize
27
+ def with_value(&b)
28
+ @mutex.synchronize { b[value] }
29
+ end
30
+
31
+ # atomically swaps the value to be `b[oldvalue]`; uses
32
+ # `with_value`
33
+ def swap!(&b)
34
+ with_value { |v| @value = b[v] }
35
+ end
36
+ end
37
+
38
+ # create an Atom
39
+ def self.atom(value)
40
+ Atom.new value
41
+ end
42
+ end
43
+
44
+ # vim: set tw=70 sw=2 sts=2 et fdm=marker :
data/lib/obfusk/lazy.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # File : obfusk/lazy.rb
4
4
  # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- # Date : 2014-06-15
5
+ # Date : 2014-06-17
6
6
  #
7
7
  # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
8
  # Licence : LGPLv3+
@@ -16,7 +16,8 @@ module Obfusk
16
16
  f = b ? b : -> { x }; v = nil; e = false
17
17
  g = -> () { unless e then v = f[]; e = true end; v }
18
18
  g.define_singleton_method(:__obfusk_lazy__?) { true }
19
- g.define_singleton_method(:_) { g[] }
19
+ g.define_singleton_method(:_) { g[] }
20
+ g.define_singleton_method(:deref) { g[] }
20
21
  g.define_singleton_method(:chain) do |m,*a,&b|
21
22
  ::Obfusk::lazy { g[].public_send(m,*a,&b) }
22
23
  end
data/lib/obfusk/list.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # File : obfusk/list.rb
4
4
  # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- # Date : 2014-06-15
5
+ # Date : 2014-06-17
6
6
  #
7
7
  # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
8
  # Licence : LGPLv3+
@@ -22,8 +22,10 @@ module Obfusk
22
22
 
23
23
  constructor :Nil
24
24
  constructor(:Cons, :head, :tail) do |cls, data, values, f|
25
- v = values.length + (f ? 1 : 0)
26
- if (k = cls.ctor_keys.length) != v
25
+ # count block as extra value; count nil tail as missing one
26
+ v = values.length + (f ? 1 : 0) -
27
+ (values.length > 1 && !data[:tail] ? 1 : 0)
28
+ if (k = cls.__adt_ctor_keys__.length) != v
27
29
  raise ArgumentError, "wrong number of arguments (#{v} for #{k})"
28
30
  end
29
31
  { head: data[:head], tail: f ? ::Obfusk.lazy(&f) :
@@ -81,16 +83,16 @@ module Obfusk
81
83
  # the list of those elements that satisfy the predicate
82
84
  def filter(p = nil, &b)
83
85
  g = p || b
84
- match Nil: -> (_) { Nil() },
85
- Cons: -> (xs) { g[xs.head] ? Cons(xs.head) { xs.tail.filter(g) }
86
- : xs.tail.filter(g) }
86
+ match Nil: -> (_) { Nil() },
87
+ Cons: -> (_) { g[head] ? Cons(head) { tail.filter(g) }
88
+ : tail.filter(g) }
87
89
  end
88
90
 
89
91
  # the list obtained by applying a function (or block) to each element
90
92
  def map(f = nil, &b)
91
93
  g = f || b
92
- match Nil: -> (_) { Nil() },
93
- Cons: -> (xs) { Cons(g[xs.head]) { xs.tail.map g } }
94
+ match Nil: -> (_) { Nil() },
95
+ Cons: -> (_) { Cons(g[head]) { tail.map g } }
94
96
  end
95
97
 
96
98
  # --
@@ -123,8 +125,8 @@ module Obfusk
123
125
 
124
126
  # append two lists
125
127
  def append(ys)
126
- match Nil: -> (_) { ys._ },
127
- Cons: -> (xs) { Cons(xs.head) { xs.tail.append ys } }
128
+ match Nil: -> (_) { ys._ },
129
+ Cons: -> (_) { Cons(head) { tail.append ys } }
128
130
  end
129
131
 
130
132
  # def reverse
@@ -146,8 +148,8 @@ module Obfusk
146
148
  # operator is lazy and must be treated as such.
147
149
  def foldr(z, f = nil, &b)
148
150
  g = f || b
149
- match Nil: -> (_) { z },
150
- Cons: -> (xs) { g[xs.head, xs.tail.chain(:foldr, z, g)] }
151
+ match Nil: -> (_) { z },
152
+ Cons: -> (_) { g[head, tail.chain(:foldr, z, g)] }
151
153
  end
152
154
 
153
155
  # def foldr1
@@ -189,8 +191,8 @@ module Obfusk
189
191
  # the prefix of length n (or the list itself if n > length)
190
192
  def take(n)
191
193
  return Nil() if n <= 0
192
- match Nil: -> (_) { Nil() },
193
- Cons: -> (xs) { Cons(xs.head) { xs.tail.take(n - 1) } }
194
+ match Nil: -> (_) { Nil() },
195
+ Cons: -> (_) { Cons(head) { tail.take(n - 1) } }
194
196
  end
195
197
 
196
198
  # def drop
@@ -238,7 +240,7 @@ module Obfusk
238
240
  # TODO
239
241
  # def self.bind_pass(m, &b)
240
242
  # m.match Nil: -> (_) { m },
241
- # Cons: -> (x) {} # concat (map f m)
243
+ # Cons: -> (_) {} # concat (map f m)
242
244
  # end
243
245
  end
244
246
 
data/lib/obfusk/monad.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # File : obfusk/monad.rb
4
4
  # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- # Date : 2014-06-15
5
+ # Date : 2014-06-16
6
6
  #
7
7
  # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
8
  # Licence : LGPLv3+
@@ -40,7 +40,8 @@ module Obfusk
40
40
  # bind m, k # discard value
41
41
  # ```
42
42
  def bind(m, k = nil, &b)
43
- b ? bind_pass(m, &b) : bind_discard(m, k)
43
+ b ? bind_pass(m, &b) : k.is_a?(::Proc) ? bind_pass(m, &k) :
44
+ bind_discard(m, k)
44
45
  end
45
46
 
46
47
  # sequentially compose two actions, passing any value produced
@@ -71,7 +72,8 @@ module Obfusk
71
72
 
72
73
  # concatenate a sequence of binds
73
74
  def pipeline(m, *fs)
74
- fs.empty? ? m : m.bind { |k| pipeline fs.first[k], *fs.drop(1) }
75
+ a = -> f, x { f.is_a?(::Proc) ? f[x] : f }
76
+ fs.empty? ? m : m.bind { |x| pipeline a[fs.first,x], *fs.drop(1) }
75
77
  end
76
78
 
77
79
  # evaluate each action in the sequence from left to right, and
@@ -94,6 +96,10 @@ module Obfusk
94
96
  self.class.public_send m, self, *a, &b
95
97
  end
96
98
  end
99
+
100
+ def >>(k)
101
+ bind k
102
+ end
97
103
  end
98
104
 
99
105
  module MonadPlus
data/lib/obfusk/monads.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # File : obfusk/monads.rb
4
4
  # Maintainer : Felix C. Stegerman <flx@obfusk.net>
5
- # Date : 2014-06-15
5
+ # Date : 2014-06-17
6
6
  #
7
7
  # Copyright : Copyright (C) 2014 Felix C. Stegerman
8
8
  # Licence : LGPLv3+
@@ -13,48 +13,140 @@ require 'obfusk/adt'
13
13
  require 'obfusk/monad'
14
14
 
15
15
  module Obfusk
16
- class Maybe
17
- include ADT
18
- include Monad
19
- include MonadPlus
16
+ module Monads
17
+ class Identity
18
+ include ADT
19
+ include Monad
20
20
 
21
- constructor :Nothing
22
- constructor :Just, :value
21
+ constructor :Identity, :run
23
22
 
24
- def self.mreturn(x)
25
- Just(x)
23
+ def self.mreturn(x)
24
+ Identity(x)
25
+ end
26
+ def self.bind_pass(m, &b)
27
+ b[m.run]
28
+ end
26
29
  end
27
- def self.bind_pass(m, &b)
28
- m.match Nothing: -> (_) { Nothing() },
29
- Just: -> (x) { b[x.value] }
30
- end
31
- def self.zero
32
- Nothing()
33
- end
34
- def self.lazy_plus(m, k)
35
- m.match Nothing: -> (_) { k._ },
36
- Just: -> (_) { m }
30
+
31
+ class Maybe
32
+ include ADT
33
+ include Monad
34
+ include MonadPlus
35
+
36
+ constructor :Nothing
37
+ constructor :Just, :value
38
+
39
+ def self.mreturn(x)
40
+ Just(x)
41
+ end
42
+ def self.bind_pass(m, &b)
43
+ m.match Nothing: -> (_) { Nothing() },
44
+ Just: -> (x) { b[x.value] }
45
+ end
46
+ def self.zero
47
+ Nothing()
48
+ end
49
+ def self.lazy_plus(m, k)
50
+ m.match Nothing: -> (_) { k._ },
51
+ Just: -> (_) { m }
52
+ end
37
53
  end
38
- end
39
54
 
40
- class Either
41
- include ADT
42
- include Monad
55
+ class Either
56
+ include ADT
57
+ include Monad
43
58
 
44
- constructor :Left , :value
45
- constructor :Right, :value
59
+ constructor :Left , :value
60
+ constructor :Right, :value
46
61
 
47
- def self.mreturn(x)
48
- Right(x)
62
+ def self.mreturn(x)
63
+ Right(x)
64
+ end
65
+ def self.bind_pass(m, &b)
66
+ m.match Left: -> (_) { m },
67
+ Right: -> (x) { b[x.value] }
68
+ end
49
69
  end
50
- def self.bind_pass(m, &b)
51
- m.match Left: -> (_) { m },
52
- Right: -> (x) { b[x.value] }
70
+
71
+ class State
72
+ include ADT
73
+ include Monad
74
+
75
+ class Pair
76
+ include ADT
77
+ constructor :Pair, :value, :state
78
+ end
79
+
80
+ Pair.import_constructors self, false
81
+
82
+ constructor :State, :run
83
+
84
+ # construct a state monad computation from a function (or block)
85
+ def self.state(f = nil, &b)
86
+ State f || b
87
+ end
88
+
89
+ # evaluate response with the given initial state and return the
90
+ # final value, discarding the final state
91
+ def self.eval(m, s)
92
+ m.run[s].value
93
+ end
94
+
95
+ # evaluate response with the given initial state and return the
96
+ # final state, discarding the final value
97
+ def self.exec(m, s)
98
+ m.run[s].state
99
+ end
100
+
101
+ # execute action on a state modified by applying a function (or
102
+ # block)
103
+ def self.with(m, f = nil, &b)
104
+ state { |s| m.run[(f || b)[s]] }
105
+ end
106
+
107
+ # get the state
108
+ def self.get
109
+ state { |s| Pair s, s }
110
+ end
111
+
112
+ # set the state
113
+ def self.put(s)
114
+ state { |_| Pair nil, s }
115
+ end
116
+
117
+ # modify the state by applying a function (or block)
118
+ def self.modify(f = nil, &b)
119
+ state { |s| Pair nil, (f || b)[s] }
120
+ end
121
+
122
+ # get a specific component of the state, using a projection
123
+ # function (or block)
124
+ def self.gets(f = nil, &b)
125
+ state { |s| Pair (f || b)[s], s }
126
+ end
127
+
128
+ def self.mreturn(x)
129
+ state { |s| Pair x, s }
130
+ end
131
+ def self.bind_pass(m, &b)
132
+ state { |s| x = m.run[s]; b[x.value].run[x.state] }
133
+ end
134
+
135
+ %w{ eval exec with }.map(&:to_sym).each do |m|
136
+ define_method(m) do |*a,&b|
137
+ self.class.public_send m, self, *a, &b
138
+ end
139
+ end
53
140
  end
54
- end
55
141
 
56
- [Maybe, Either].each { |x| x.import_constructors self }
142
+ [Maybe, Either].each do |x|
143
+ x.import_constructors self
144
+ end
57
145
 
146
+ [Identity, State].each do |x|
147
+ x.import_constructors self, false
148
+ end
149
+ end
58
150
  end
59
151
 
60
152
  # vim: set tw=70 sw=2 sts=2 et fdm=marker :
@@ -1,4 +1,4 @@
1
1
  module Obfusk
2
- VERSION = '0.1.1'
3
- DATE = '2014-06-16'
2
+ VERSION = '0.1.2'
3
+ DATE = '2014-06-18'
4
4
  end
data/lib/obfusk.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'obfusk/adt'
2
+ require 'obfusk/atom'
2
3
  require 'obfusk/lazy'
3
4
  require 'obfusk/list'
4
5
  require 'obfusk/monad'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obfusk
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
  - Felix C. Stegerman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-16 00:00:00.000000000 Z
11
+ date: 2014-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -65,6 +65,7 @@ files:
65
65
  - Rakefile
66
66
  - lib/obfusk.rb
67
67
  - lib/obfusk/adt.rb
68
+ - lib/obfusk/atom.rb
68
69
  - lib/obfusk/lazy.rb
69
70
  - lib/obfusk/list.rb
70
71
  - lib/obfusk/monad.rb