obfusk 0.1.1 → 0.1.2

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: 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