halu 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ == 0.0.1 2007-08-11
2
+
3
+ * �ŏ��̃����[�X�B
4
+
5
+ * Prelude��List�֘A�̊֐��������B
@@ -0,0 +1 @@
1
+ Ruby's License
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ example/fib.rb
7
+ example/insert_sort.rb
8
+ example/select_sort.rb
9
+ lib/halu.rb
10
+ lib/halu/version.rb
11
+ setup.rb
12
+ test/test_halu.rb
13
+ test/test_helper.rb
@@ -0,0 +1,28 @@
1
+ Halu ... HAskell-like List Utility
2
+ ==================================
3
+
4
+ ������ĉ��H
5
+ -----------
6
+ Haskell���ۂ�List���C�u�����ł��B
7
+ Haskell��Prelude�̃��X�g�֘A�֐���S�Ď������Ă��܂��B
8
+
9
+ �C���X�g�[��
10
+ ------------
11
+ Gem�ŃC���X�g�[�����Ă��������B
12
+
13
+ $ gem install cohi
14
+
15
+ �}�j���A��
16
+ ----------
17
+ ���݂܂���B�����Ă��܂���B
18
+ lib/halu.rb���Q�Ƃ��Ă��������B
19
+ Haskell��Prelude�̃}�j���A�����Q�l�ɂȂ�Ǝv���܂��B
20
+
21
+ �T���v��
22
+ --------
23
+ example�f�B���N�g�����Q�Ƃ��Ă��������B
24
+
25
+ �T�|�[�g
26
+ --------
27
+ ��������܂����牺�L�܂ł��肢���܂��B
28
+ <tanaka.shinya@gmail.com>
@@ -0,0 +1,123 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+
12
+ include FileUtils
13
+ require File.join(File.dirname(__FILE__), 'lib', 'halu', 'version')
14
+
15
+ AUTHOR = 'TANAKA Shin-ya(id:ha-tan)' # can also be an array of Authors
16
+ EMAIL = "tanaka.shinya@gmail.com"
17
+ DESCRIPTION = "Halu ... HAskell-like List Utility"
18
+ GEM_NAME = 'halu' # what ppl will type to install your gem
19
+
20
+ @config_file = "~/.rubyforge/user-config.yml"
21
+ @config = nil
22
+ def rubyforge_username
23
+ unless @config
24
+ begin
25
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
26
+ rescue
27
+ puts <<-EOS
28
+ ERROR: No rubyforge config file found: #{@config_file}"
29
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
30
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
31
+ EOS
32
+ exit
33
+ end
34
+ end
35
+ @rubyforge_username ||= @config["username"]
36
+ end
37
+
38
+ RUBYFORGE_PROJECT = 'halu' # The unix name for your project
39
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
40
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
41
+
42
+ NAME = "halu"
43
+ REV = nil
44
+ # UNCOMMENT IF REQUIRED:
45
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
46
+ VERS = Halu::VERSION::STRING + (REV ? ".#{REV}" : "")
47
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
48
+ RDOC_OPTS = ['--quiet', '--title', 'halu documentation',
49
+ "--opname", "index.html",
50
+ "--line-numbers",
51
+ "--main", "README",
52
+ "--inline-source"]
53
+
54
+ class Hoe
55
+ def extra_deps
56
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
57
+ end
58
+ end
59
+
60
+ # Generate all the Rake tasks
61
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
62
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
63
+ p.author = AUTHOR
64
+ p.description = DESCRIPTION
65
+ p.email = EMAIL
66
+ p.summary = DESCRIPTION
67
+ p.url = HOMEPATH
68
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
69
+ p.test_globs = ["test/**/test_*.rb"]
70
+ p.clean_globs |= CLEAN #An array of file patterns to delete on clean.
71
+
72
+ # == Optional
73
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
74
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
75
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
76
+ end
77
+
78
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\n\n")
79
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
80
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
81
+
82
+ desc 'Generate website files'
83
+ task :website_generate do
84
+ Dir['website/**/*.txt'].each do |txt|
85
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
86
+ end
87
+ end
88
+
89
+ desc 'Upload website files to rubyforge'
90
+ task :website_upload do
91
+ host = "#{rubyforge_username}@rubyforge.org"
92
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
93
+ local_dir = 'website'
94
+ sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
95
+ end
96
+
97
+ desc 'Generate and upload website files'
98
+ task :website => [:website_generate, :website_upload, :publish_docs]
99
+
100
+ desc 'Release the website and new gem version'
101
+ task :deploy => [:check_version, :website, :release] do
102
+ puts "Remember to create SVN tag:"
103
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
104
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
105
+ puts "Suggested comment:"
106
+ puts "Tagging release #{CHANGES}"
107
+ end
108
+
109
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
110
+ task :local_deploy => [:website_generate, :install_gem]
111
+
112
+ task :check_version do
113
+ unless ENV['VERSION']
114
+ puts 'Must pass a VERSION=x.y.z release version'
115
+ exit
116
+ end
117
+ unless ENV['VERSION'] == VERS
118
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
119
+ exit
120
+ end
121
+ end
122
+
123
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- compile-command: "ruby fib.rb" -*-
3
+
4
+ $LOAD_PATH << '../lib'
5
+ require 'halu'
6
+
7
+ include Halu
8
+
9
+ # �t�B�{�i�b�`����̃��X�g(�~��)��Ԃ��B
10
+ def fib(n)
11
+ case n
12
+ when 0
13
+ List[0]
14
+ when 1
15
+ fib(0) >> 1
16
+ when 2
17
+ fib(1) >> 1
18
+ else
19
+ xs = fib(n - 1)
20
+ xs >> (xs.head + xs.tail.head)
21
+ end
22
+ end
23
+
24
+ p fib(0) # => Halu::List[0]
25
+ p fib(3) # => Halu::List[2, 1, 1, 0]
26
+ p fib(5) # => Halu::List[5, 3, 2, 1, 1, 0]
27
+ p fib(20).head # => 6765
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- compile-command: "ruby insert_sort.rb" -*-
3
+
4
+ $LOAD_PATH << '../lib'
5
+ require 'halu'
6
+
7
+ include Halu
8
+
9
+ def insert_sort(xs)
10
+ xs.fold(EMPTY_LIST) do |rs, x|
11
+ rs1, rs2 = rs.span {|h| h < x} # rs��x��}������ӏ���2�‚ɕ�����B
12
+ rs1.append(rs2 >> x) # rs2�̓���x���‚��đS�̂�rs1�̌�ɂ‚���B
13
+ end
14
+ end
15
+
16
+ p insert_sort(List[8, 4, 3, 7, 6, 5, 2, 1])
17
+ # => Halu::List[1, 2, 3, 4, 5, 6, 7, 8]
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- compile-command: "ruby select_sort.rb" -*-
3
+
4
+ $LOAD_PATH << '../lib'
5
+ require 'halu'
6
+
7
+ include Halu
8
+
9
+ def select_sort(xs)
10
+ if xs.null?
11
+ EMPTY_LIST
12
+ else
13
+ min = xs.minimum # �ŏ��̗v�f�B
14
+ xs2 = xs.filter {|x| x != min } # ����ȊO�̗v�f�B
15
+ select_sort(xs2) >> min # �ċA�I�Ƀ\�[�g�B
16
+ # �擪�ɍŏ��̗v�f�������‚���B
17
+ end
18
+ end
19
+
20
+ p select_sort(List[8, 4, 3, 7, 6, 5, 2, 1])
21
+ # => Halu::List[1, 2, 3, 4, 5, 6, 7, 8]
@@ -0,0 +1,502 @@
1
+ module Halu
2
+ class List
3
+ include Enumerable
4
+
5
+ def List::[](*ary)
6
+ root = list = EMPTY_LIST
7
+ ary.each do |h|
8
+ list = list << h
9
+ root = list if root.null?
10
+ end
11
+ root
12
+ end
13
+
14
+ def initialize(h, t = EMPTY_LIST)
15
+ @head = h
16
+ @tail = t
17
+ end
18
+
19
+ def each
20
+ list = self
21
+ loop do
22
+ yield(list.head)
23
+ break if list.tail.null?
24
+ list = list.tail
25
+ end
26
+ self
27
+ end
28
+
29
+ def to_a
30
+ inject([]) {|ary, h| ary << h }
31
+ end
32
+
33
+ def inspect
34
+ self.class.to_s + to_a.inspect
35
+ end
36
+
37
+ def last_list
38
+ list = self
39
+ list = list.tail until list.tail.null?
40
+ list
41
+ end
42
+ private :last_list
43
+
44
+ def <<(h)
45
+ last_list.tail = List.new(h)
46
+ end
47
+
48
+ def >>(h)
49
+ list = List.new(h)
50
+ list.tail = self
51
+ list
52
+ end
53
+
54
+ # map :: (a -> b) -> [a] -> [b]
55
+ def map2
56
+ root = list = EMPTY_LIST
57
+ each do |h|
58
+ list = list << yield(h)
59
+ root = list if root.null?
60
+ end
61
+ root
62
+ end
63
+
64
+ # (++) :: [a] -> [a] -> [a]
65
+ def append(list)
66
+ last_list.tail = list
67
+ self
68
+ end
69
+
70
+ # filter :: (a -> Bool) -> [a] -> [a]
71
+ def filter
72
+ root = list = EMPTY_LIST
73
+ each do |h|
74
+ if yield(h)
75
+ list = list << h
76
+ root = list if root.null?
77
+ end
78
+ end
79
+ root
80
+ end
81
+
82
+ # head :: [a] -> a
83
+ attr_accessor :head
84
+
85
+ # last :: [a] -> a
86
+ def last
87
+ inject(nil) {|r, h| h }
88
+ end
89
+
90
+ # tail :: [a] -> [a]
91
+ attr_accessor :tail
92
+
93
+ # init :: [a] -> [a]
94
+ def init
95
+ root = list = prelist = EMPTY_LIST
96
+ each do |h|
97
+ prelist = list
98
+ list = list << h
99
+ root = list if root.null?
100
+ end
101
+ prelist.tail = EMPTY_LIST
102
+ root
103
+ end
104
+
105
+ # null :: [a] -> Bool
106
+ def null?
107
+ self == EMPTY_LIST
108
+ end
109
+
110
+ # length :: [a] -> Int
111
+ def length
112
+ inject(0) {|r, h| r.succ }
113
+ end
114
+
115
+ # (!!) :: [a] -> Int -> a
116
+ def at(i)
117
+ each_with_index do |h, j|
118
+ return h if i == j
119
+ end
120
+ nil
121
+ end
122
+
123
+ # reverse :: [a] -> [a]
124
+ def reverse
125
+ inject(EMPTY_LIST) {|list, h| list >> h }
126
+ end
127
+
128
+ # foldl :: (a -> b -> a) -> a -> [b] -> a
129
+ # foldl1 :: (a -> a -> a) -> [a] -> a
130
+ # foldr :: (a -> b -> b) -> b -> [a] -> b
131
+ # foldr1 :: (a -> a -> a) -> [a] -> a
132
+ def fold(x)
133
+ inject(x) {|*arg| yield(*arg) }
134
+ end
135
+
136
+ def fold1
137
+ inject {|*arg| yield(*arg) }
138
+ end
139
+
140
+ # and :: [Bool] -> Bool
141
+ def and?
142
+ each do |h|
143
+ return false unless h
144
+ end
145
+ true
146
+ end
147
+
148
+ # or :: [Bool] -> Bool
149
+ def or?
150
+ each do |h|
151
+ return true if h
152
+ end
153
+ false
154
+ end
155
+
156
+ # any :: (a -> Bool) -> [a] -> Bool
157
+ # Enumerable#any?
158
+
159
+ # all :: (a -> Bool) -> [a] -> Bool
160
+ # Enumerable#all?
161
+
162
+ # sum :: Num a => [a] -> a
163
+ def sum
164
+ inject(0) {|r, h| r + h }
165
+ end
166
+
167
+ # product :: Num a => [a] -> a
168
+ def product
169
+ inject(1) {|r, h| r * h }
170
+ end
171
+
172
+ # concat :: [[a]] -> [a]
173
+ def concat
174
+ root = list = EMPTY_LIST
175
+ each do |h|
176
+ list.append h
177
+ list = h
178
+ root = list if root.null?
179
+ end
180
+ root
181
+ end
182
+
183
+ # concatMap :: (a -> [b]) -> [a] -> [b]
184
+ def concat_map(&block)
185
+ map2(&block).concat
186
+ end
187
+
188
+ # maximum :: Ord a => [a] -> a
189
+ alias :maximum :max
190
+
191
+ # minimum :: Ord a => [a] -> a
192
+ alias :minimum :min
193
+
194
+ # scanl :: (a -> b -> a) -> a -> [b] -> [a]
195
+ # scanl1 :: (a -> a -> a) -> [a] -> [a]
196
+ # scanr :: (a -> b -> b) -> b -> [a] -> [b]
197
+ # scanr1 :: (a -> a -> a) -> [a] -> [a]
198
+ def scan(x)
199
+ root = rs = EMPTY_LIST
200
+ inject(x) do |r, h|
201
+ root = rs = rs << r if root.null?
202
+ r2 = yield(r, h)
203
+ rs = rs << r2
204
+ r2
205
+ end
206
+ root
207
+ end
208
+
209
+ def scan1
210
+ root = rs = EMPTY_LIST
211
+ inject do |r, h|
212
+ root = rs = rs << r if root.null?
213
+ r2 = yield(r, h)
214
+ rs = rs << r2
215
+ r2
216
+ end
217
+ root
218
+ end
219
+
220
+ # replicate :: Int -> a -> [a]
221
+ def List::replicate(n, h)
222
+ root = list = EMPTY_LIST
223
+ n.times do
224
+ list = list << h
225
+ root = list if root.null?
226
+ end
227
+ root
228
+ end
229
+
230
+ # take :: Int -> [a] -> [a]
231
+ def take(n)
232
+ root = list = EMPTY_LIST
233
+ each_with_index do |h, i|
234
+ break if i >= n
235
+ list = list << h
236
+ root = list if root.null?
237
+ end
238
+ root
239
+ end
240
+
241
+ # drop :: Int -> [a] -> [a]
242
+ def drop(n)
243
+ root = list = EMPTY_LIST
244
+ each_with_index do |h, i|
245
+ if i >= n
246
+ list = list << h
247
+ root = list if root.null?
248
+ end
249
+ end
250
+ root
251
+ end
252
+
253
+ # splitAt :: Int -> [a] -> ([a], [a])
254
+ def split_at(n)
255
+ root1 = root2 = list1 = list2 = EMPTY_LIST
256
+ each_with_index do |h, i|
257
+ if i < n
258
+ list1 = list1 << h
259
+ root1 = list1 if root1.null?
260
+ else
261
+ list2 = list2 << h
262
+ root2 = list2 if root2.null?
263
+ end
264
+ end
265
+ [root1, root2]
266
+ end
267
+
268
+ # takeWhile :: (a -> Bool) -> [a] -> [a]
269
+ def take_while
270
+ root = list = EMPTY_LIST
271
+ each do |h|
272
+ break unless yield(h)
273
+ list = list << h
274
+ root = list if root.null?
275
+ end
276
+ root
277
+ end
278
+
279
+ # dropWhile :: (a -> Bool) -> [a] -> [a]
280
+ def drop_while
281
+ root = list = EMPTY_LIST
282
+ drop_f = true
283
+ each do |h|
284
+ if drop_f
285
+ drop_f = false unless yield(h)
286
+ end
287
+ unless drop_f
288
+ list = list << h
289
+ root = list if root.null?
290
+ end
291
+ end
292
+ root
293
+ end
294
+
295
+ # span :: (a -> Bool) -> [a] -> ([a], [a])
296
+ def span
297
+ root1 = root2 = list1 = list2 = EMPTY_LIST
298
+ span_f = false
299
+ each do |h|
300
+ unless span_f
301
+ span_f = true unless yield(h)
302
+ end
303
+ unless span_f
304
+ list1 = list1 << h
305
+ root1 = list1 if root1.null?
306
+ else
307
+ list2 = list2 << h
308
+ root2 = list2 if root2.null?
309
+ end
310
+ end
311
+ [root1, root2]
312
+ end
313
+
314
+ # break :: (a -> Bool) -> [a] -> ([a], [a])
315
+ def break
316
+ root1 = root2 = list1 = list2 = EMPTY_LIST
317
+ span_f = false
318
+ each do |h|
319
+ unless span_f
320
+ span_f = true if yield(h)
321
+ end
322
+ unless span_f
323
+ list1 = list1 << h
324
+ root1 = list1 if root1.null?
325
+ else
326
+ list2 = list2 << h
327
+ root2 = list2 if root2.null?
328
+ end
329
+ end
330
+ [root1, root2]
331
+ end
332
+
333
+ # elem :: Eq a => a -> [a] -> Bool
334
+ def elem(h)
335
+ list = EMPTY_LIST
336
+ each do |h2|
337
+ return true if h == h2
338
+ end
339
+ false
340
+ end
341
+
342
+ # notElem :: Eq a => a -> [a] -> Bool
343
+ def not_elem(h)
344
+ not elem(h)
345
+ end
346
+
347
+ # lookup :: Eq a => a -> [(a, b)] -> Maybe b
348
+ def lookup(h)
349
+ list = EMPTY_LIST
350
+ each do |a|
351
+ return a[1] if h == a[0]
352
+ end
353
+ nil
354
+ end
355
+
356
+ # zip :: [a] -> [b] -> [(a, b)]
357
+ def zip2(list2)
358
+ return EMPTY_LIST if null?
359
+ return EMPTY_LIST if list2.null?
360
+ root = list = EMPTY_LIST
361
+ list1 = self
362
+ loop do
363
+ list = list << [list1.head, list2.head]
364
+ root = list if root.null?
365
+ break if list1.tail.null?
366
+ break if list2.tail.null?
367
+ list1 = list1.tail
368
+ list2 = list2.tail
369
+ end
370
+ root
371
+ end
372
+
373
+ # zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
374
+ def zip3(list2, list3)
375
+ return EMPTY_LIST if null?
376
+ return EMPTY_LIST if list2.null?
377
+ return EMPTY_LIST if list3.null?
378
+ root = list = EMPTY_LIST
379
+ list1 = self
380
+ loop do
381
+ list = list << [list1.head, list2.head, list3.head]
382
+ root = list if root.null?
383
+ break if list1.tail.null?
384
+ break if list2.tail.null?
385
+ break if list3.tail.null?
386
+ list1 = list1.tail
387
+ list2 = list2.tail
388
+ list3 = list3.tail
389
+ end
390
+ root
391
+ end
392
+
393
+ # zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
394
+ def zip_with(list2)
395
+ return EMPTY_LIST if null?
396
+ return EMPTY_LIST if list2.null?
397
+ root = list = EMPTY_LIST
398
+ list1 = self
399
+ loop do
400
+ list = list << yield(list1.head, list2.head)
401
+ root = list if root.null?
402
+ break if list1.tail.null?
403
+ break if list2.tail.null?
404
+ list1 = list1.tail
405
+ list2 = list2.tail
406
+ end
407
+ root
408
+ end
409
+
410
+ # zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
411
+ def zip_with3(list2, list3)
412
+ return EMPTY_LIST if null?
413
+ return EMPTY_LIST if list2.null?
414
+ return EMPTY_LIST if list3.null?
415
+ root = list = EMPTY_LIST
416
+ list1 = self
417
+ loop do
418
+ list = list << yield(list1.head, list2.head, list3.head)
419
+ root = list if root.null?
420
+ break if list1.tail.null?
421
+ break if list2.tail.null?
422
+ break if list3.tail.null?
423
+ list1 = list1.tail
424
+ list2 = list2.tail
425
+ list3 = list3.tail
426
+ end
427
+ root
428
+ end
429
+
430
+ # unzip :: [(a, b)] -> ([a], [b])
431
+ def unzip
432
+ root1 = root2 = list1 = list2 = EMPTY_LIST
433
+ each do |h|
434
+ list1 = list1 << h[0]
435
+ list2 = list2 << h[1]
436
+ root1 = list1 if root1.null?
437
+ root2 = list2 if root2.null?
438
+ end
439
+ [root1, root2]
440
+ end
441
+
442
+ # unzip3 :: [(a, b, c)] -> ([a], [b], [c])
443
+ def unzip3
444
+ root1 = root2 = root3 = list1 = list2 = list3 = EMPTY_LIST
445
+ each do |h|
446
+ list1 = list1 << h[0]
447
+ list2 = list2 << h[1]
448
+ list3 = list3 << h[2]
449
+ root1 = list1 if root1.null?
450
+ root2 = list2 if root2.null?
451
+ root3 = list3 if root3.null?
452
+ end
453
+ [root1, root2, root3]
454
+ end
455
+
456
+ # unlines :: [String] -> String
457
+ def unlines(nl = "\n")
458
+ inject('') do |s, h|
459
+ s + h.to_s + nl
460
+ end
461
+ end
462
+
463
+ # unwords :: [String] -> String
464
+ def unwords(sp = ' ')
465
+ inject('') do |s, h|
466
+ s + (s.empty? ? '' : sp) + h.to_s
467
+ end
468
+ end
469
+ end
470
+
471
+ class EmptyList < List
472
+ def initialize
473
+ end
474
+
475
+ def each
476
+ end
477
+
478
+ def to_a
479
+ []
480
+ end
481
+
482
+ def <<(h)
483
+ List.new(h)
484
+ end
485
+
486
+ def >>(h)
487
+ List.new(h)
488
+ end
489
+
490
+ def append(list)
491
+ list
492
+ end
493
+
494
+ def scan(x)
495
+ List.new(x)
496
+ end
497
+ end
498
+
499
+ EMPTY_LIST = EmptyList.new
500
+ end
501
+
502
+ require 'halu/version'