prelude 0.0.1
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.
- data/CHANGELOG +7 -0
- data/COPYING +339 -0
- data/README +47 -0
- data/Rakefile +109 -0
- data/TODO +6 -0
- data/lib/prelude.rb +66 -0
- data/lib/prelude/list.rb +572 -0
- data/lib/prelude/monad.rb +39 -0
- data/lib/prelude/tuple.rb +64 -0
- data/test/tc_higher.rb +89 -0
- data/test/tc_list.rb +772 -0
- data/test/tc_tuple.rb +44 -0
- data/test/ts_prelude.rb +35 -0
- metadata +59 -0
data/TODO
ADDED
data/lib/prelude.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#--
|
2
|
+
# This file is part of the Prelude library that provides tools to
|
3
|
+
# enable Haskell style functional programming in Ruby.
|
4
|
+
#
|
5
|
+
# http://prelude.rubyforge.org
|
6
|
+
#
|
7
|
+
# Copyright (C) 2006 APP Design, Inc.
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation; either version 2 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# This program is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License along
|
20
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
21
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
22
|
+
#++
|
23
|
+
#
|
24
|
+
# $Id: prelude.rb 2 2006-08-25 00:11:17Z prelude $
|
25
|
+
|
26
|
+
$:.unshift(File.dirname(__FILE__))
|
27
|
+
|
28
|
+
require 'prelude/list'
|
29
|
+
require 'prelude/tuple'
|
30
|
+
require 'prelude/monad'
|
31
|
+
|
32
|
+
module Prelude
|
33
|
+
VERSION='0.0.1'
|
34
|
+
end # Prelude
|
35
|
+
|
36
|
+
class Symbol
|
37
|
+
|
38
|
+
# See http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc for the detailed discussion
|
39
|
+
def to_proc
|
40
|
+
proc { |obj, *args| obj.send(self, *args) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def curry(one, *args)
|
44
|
+
proc { |*args| self.to_proc.call(one, *args) }
|
45
|
+
end
|
46
|
+
|
47
|
+
end # Symbol
|
48
|
+
|
49
|
+
class Proc
|
50
|
+
|
51
|
+
# See also http://rubyforge.org/projects/rubymurray/ for an
|
52
|
+
# elaborate port of Perl's Sub::Curry library
|
53
|
+
def curry(one, *args)
|
54
|
+
proc{ |*args| self.call(one, *args)}
|
55
|
+
end
|
56
|
+
|
57
|
+
# This is will serve as an infix composition operator
|
58
|
+
def <<(*args)
|
59
|
+
if (1==args.length) && args[0].is_a?(Proc)
|
60
|
+
proc {|*a| self.call(args[0].call(*a)) }
|
61
|
+
else
|
62
|
+
self.call(*args.flatten)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end # Proc
|
data/lib/prelude/list.rb
ADDED
@@ -0,0 +1,572 @@
|
|
1
|
+
#--
|
2
|
+
# This file is part of the Prelude library that provides tools to
|
3
|
+
# enable Haskell style functional programming in Ruby.
|
4
|
+
#
|
5
|
+
# http://prelude.rubyforge.org
|
6
|
+
#
|
7
|
+
# Copyright (C) 2006 APP Design, Inc.
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation; either version 2 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# This program is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License along
|
20
|
+
# with this program; if not, write to the Free Software Foundation, Inc.,
|
21
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module Prelude
|
25
|
+
|
26
|
+
# $Id: list.rb 2 2006-08-25 00:11:17Z prelude $
|
27
|
+
#
|
28
|
+
# This code is inspired in part by Hipster, <hipster xs4all.nl> (a.k.a. Michel
|
29
|
+
# van de Ven), and his original sketch was initially located at
|
30
|
+
# http://www.xs4all.nl/~hipster/lib/ruby/haskell
|
31
|
+
#
|
32
|
+
# This eventually needs to be implemented with lazy lists, see
|
33
|
+
# http://lazylist.rubyforge.org for details
|
34
|
+
#
|
35
|
+
# I used the signatures of Haskell's List.hs file in order not to forget to implement
|
36
|
+
# the functions defined there and to remind of what was intended.
|
37
|
+
class List < Array
|
38
|
+
|
39
|
+
# Array compatibility functions
|
40
|
+
alias array_plus +
|
41
|
+
|
42
|
+
def +(o)
|
43
|
+
List.new(self.array_plus(o))
|
44
|
+
end
|
45
|
+
|
46
|
+
# , head -- :: [a] -> a
|
47
|
+
def head
|
48
|
+
self[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
# , last -- :: [a] -> a
|
52
|
+
# already defined by the Array
|
53
|
+
|
54
|
+
# , tail -- :: [a] -> [a]
|
55
|
+
def tail
|
56
|
+
self[1..-1]
|
57
|
+
end
|
58
|
+
|
59
|
+
# , init -- :: [a] -> [a]
|
60
|
+
def init
|
61
|
+
self[0..-2]
|
62
|
+
end
|
63
|
+
|
64
|
+
# , null -- :: [a] -> Bool
|
65
|
+
def null
|
66
|
+
size == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
# , length -- :: [a] -> Int
|
70
|
+
# Implemented by Array
|
71
|
+
|
72
|
+
# -- * List transformations
|
73
|
+
# , map -- :: (a -> b) -> [a] -> [b]
|
74
|
+
# Implemented by Array
|
75
|
+
|
76
|
+
# , reverse -- :: [a] -> [a]
|
77
|
+
# Implemented by Array
|
78
|
+
|
79
|
+
# , intersperse -- :: a -> [a] -> [a]
|
80
|
+
def intersperse
|
81
|
+
warn "Method 'intersperse' is not implemented yet." if $VERBOSE
|
82
|
+
return []
|
83
|
+
end
|
84
|
+
|
85
|
+
# , transpose -- :: [[a]] -> [[a]]
|
86
|
+
# Implemented by Array
|
87
|
+
|
88
|
+
# -- * Reducing lists (folds)
|
89
|
+
|
90
|
+
# , foldl -- :: (a -> b -> a) -> a -> [b] -> a
|
91
|
+
|
92
|
+
# Classic recursive functional definition causes stack overflow for
|
93
|
+
# arrays of any usable size... So don't use it, it's here for
|
94
|
+
# demonstration purposes only
|
95
|
+
def f_foldl(s, &block)
|
96
|
+
empty? ? s : tail.f_foldl(block.call(s, head), &block)
|
97
|
+
end
|
98
|
+
|
99
|
+
# This is a more pedestrian iterative version.
|
100
|
+
def foldl(s, &block)
|
101
|
+
inject(s){ |a,b| block.call(a,b) }
|
102
|
+
end
|
103
|
+
|
104
|
+
# , foldl' -- :: (a -> b -> a) -> a -> [b] -> a
|
105
|
+
def foldl_
|
106
|
+
warn "Method 'foldl_' is not implemented yet." if $VERBOSE
|
107
|
+
return []
|
108
|
+
end
|
109
|
+
|
110
|
+
# , foldl1 -- :: (a -> a -> a) -> [a] -> a
|
111
|
+
def foldl1(&block)
|
112
|
+
tail.foldl(head, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
# , foldl1' -- :: (a -> a -> a) -> [a] -> a
|
116
|
+
def foldl1_
|
117
|
+
warn "Method 'foldl1_' is not implemented yet." if $VERBOSE
|
118
|
+
return []
|
119
|
+
end
|
120
|
+
|
121
|
+
# , foldr -- :: (a -> b -> b) -> b -> [a] -> b
|
122
|
+
def foldr(s, &block)
|
123
|
+
inject(s){ |a,b| block.call(b, a) }
|
124
|
+
end
|
125
|
+
|
126
|
+
# , foldr1 -- :: (a -> a -> a) -> [a] -> a
|
127
|
+
def foldr1(&block)
|
128
|
+
tail.foldr(head, &block)
|
129
|
+
end
|
130
|
+
|
131
|
+
# -- ** Special folds
|
132
|
+
|
133
|
+
# , concat -- :: [[a]] -> [a]
|
134
|
+
# Implemented by Array but semantics is different
|
135
|
+
def concat
|
136
|
+
flatten
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# , concatMap -- :: (a -> [b]) -> [a] -> [b]
|
141
|
+
def concat_map
|
142
|
+
warn "Method 'concatMap' is not implemented yet." if $VERBOSE
|
143
|
+
return []
|
144
|
+
end
|
145
|
+
alias concatMap concat_map
|
146
|
+
|
147
|
+
# , and -- :: [Bool] -> Bool
|
148
|
+
def and
|
149
|
+
foldr(true){|x,y| x && y}
|
150
|
+
end
|
151
|
+
|
152
|
+
# , or -- :: [Bool] -> Bool
|
153
|
+
def or
|
154
|
+
foldr(false){|x,y| (x || y)}
|
155
|
+
end
|
156
|
+
|
157
|
+
# , any -- :: (a -> Bool) -> [a] -> Bool
|
158
|
+
def any(&block)
|
159
|
+
each{|e| return true if block.call(e)}
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
|
163
|
+
# , all -- :: (a -> Bool) -> [a] -> Bool
|
164
|
+
def all(&block)
|
165
|
+
each{|e| return false unless block.call(e)}
|
166
|
+
return true
|
167
|
+
end
|
168
|
+
|
169
|
+
# , sum -- :: (Num a) => [a] -> a
|
170
|
+
def sum
|
171
|
+
warn "Method 'sum' is not implemented yet." if $VERBOSE
|
172
|
+
return []
|
173
|
+
end
|
174
|
+
|
175
|
+
# , product -- :: (Num a) => [a] -> a
|
176
|
+
def product
|
177
|
+
warn "Method 'product' is not implemented yet." if $VERBOSE
|
178
|
+
return []
|
179
|
+
end
|
180
|
+
|
181
|
+
# , maximum -- :: (Ord a) => [a] -> a
|
182
|
+
def maximum
|
183
|
+
warn "Method 'maximum' is not implemented yet." if $VERBOSE
|
184
|
+
return []
|
185
|
+
end
|
186
|
+
|
187
|
+
# , minimum -- :: (Ord a) => [a] -> a
|
188
|
+
def minimum
|
189
|
+
warn "Method 'minimum' is not implemented yet." if $VERBOSE
|
190
|
+
return []
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
# -- * Building lists
|
195
|
+
|
196
|
+
# -- ** Scans
|
197
|
+
# , scanl -- :: (a -> b -> a) -> a -> [b] -> [a]
|
198
|
+
def scanl(s, &block)
|
199
|
+
inject([s]){ |a,b| a << block.call(a.last,b) }
|
200
|
+
end
|
201
|
+
|
202
|
+
# , scanl1 -- :: (a -> a -> a) -> [a] -> [a]
|
203
|
+
def scanl1(&block)
|
204
|
+
tail.scanl(head, &block)
|
205
|
+
end
|
206
|
+
|
207
|
+
# , scanr -- :: (a -> b -> b) -> b -> [a] -> [b]
|
208
|
+
def scanr(s, &block)
|
209
|
+
inject([s]){ |a,b| a << block.call(b, a.last) }
|
210
|
+
end
|
211
|
+
|
212
|
+
# , scanr1 -- :: (a -> a -> a) -> [a] -> [a]
|
213
|
+
def scanr1(&block)
|
214
|
+
tail.scanr(head, &block)
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
# -- ** Accumulating maps
|
219
|
+
# , mapAccumL -- :: (a -> b -> (a,c)) -> a -> [b] -> (a,[c])
|
220
|
+
def map_accum_l
|
221
|
+
warn "Method 'map_accum_l' is not implemented yet." if $VERBOSE
|
222
|
+
return []
|
223
|
+
end
|
224
|
+
alias mapAccumL map_accum_l
|
225
|
+
|
226
|
+
# , mapAccumR -- :: (a -> b -> (a,c)) -> a -> [b] -> (a,[c])
|
227
|
+
def map_accum_r
|
228
|
+
warn "Method 'map_accum_r' is not implemented yet." if $VERBOSE
|
229
|
+
return []
|
230
|
+
end
|
231
|
+
alias mapAccumR map_accum_r
|
232
|
+
|
233
|
+
|
234
|
+
# -- ** Infinite lists
|
235
|
+
# , iterate -- :: (a -> a) -> a -> [a]
|
236
|
+
def iterate
|
237
|
+
warn "Method 'iterate' is not implemented yet." if $VERBOSE
|
238
|
+
return []
|
239
|
+
end
|
240
|
+
|
241
|
+
# , repeat -- :: a -> [a]
|
242
|
+
def repeat
|
243
|
+
warn "Method 'repeat' is not implemented yet." if $VERBOSE
|
244
|
+
return []
|
245
|
+
end
|
246
|
+
|
247
|
+
# , replicate -- :: Int -> a -> [a]
|
248
|
+
def replicate
|
249
|
+
warn "Method 'replicate' is not implemented yet." if $VERBOSE
|
250
|
+
return []
|
251
|
+
end
|
252
|
+
|
253
|
+
# , cycle -- :: [a] -> [a]
|
254
|
+
def cycle
|
255
|
+
warn "Method 'cycle' is not implemented yet." if $VERBOSE
|
256
|
+
return []
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
# -- ** Unfolding
|
261
|
+
# , unfoldr -- :: (b -> Maybe (a, b)) -> b -> [a]
|
262
|
+
def unfoldr
|
263
|
+
warn "Method 'unfoldr' is not implemented yet." if $VERBOSE
|
264
|
+
return []
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
# -- * Sublists
|
269
|
+
|
270
|
+
# -- ** Extracting sublists
|
271
|
+
# , take -- :: Int -> [a] -> [a]
|
272
|
+
def take(n)
|
273
|
+
self[0..(n-1)]
|
274
|
+
end
|
275
|
+
|
276
|
+
# , drop -- :: Int -> [a] -> [a]
|
277
|
+
def drop(n)
|
278
|
+
self[n..-1]
|
279
|
+
end
|
280
|
+
|
281
|
+
# , splitAt -- :: Int -> [a] -> ([a], [a])
|
282
|
+
def split_at(n)
|
283
|
+
[take(n), drop(n)]
|
284
|
+
end
|
285
|
+
alias splitAt split_at
|
286
|
+
|
287
|
+
# , takeWhile -- :: (a -> Bool) -> [a] -> [a]
|
288
|
+
def take_while
|
289
|
+
r = []
|
290
|
+
each{ |e|
|
291
|
+
break unless yield(e)
|
292
|
+
r << e
|
293
|
+
}
|
294
|
+
r
|
295
|
+
end
|
296
|
+
alias takeWhile take_while
|
297
|
+
|
298
|
+
# , dropWhile -- :: (a -> Bool) -> [a] -> [a]
|
299
|
+
def drop_while
|
300
|
+
r = []
|
301
|
+
each{ |e|
|
302
|
+
next if yield(e)
|
303
|
+
r << e
|
304
|
+
}
|
305
|
+
r
|
306
|
+
end
|
307
|
+
alias dropWhile drop_while
|
308
|
+
|
309
|
+
# , span -- :: (a -> Bool) -> [a] -> ([a], [a])
|
310
|
+
def span(&block)
|
311
|
+
[take_while(&block), drop_while(&block)]
|
312
|
+
end
|
313
|
+
|
314
|
+
# , break -- :: (a -> Bool) -> [a] -> ([a], [a])
|
315
|
+
def break
|
316
|
+
warn "Method 'break' is not implemented yet." if $VERBOSE
|
317
|
+
return []
|
318
|
+
end
|
319
|
+
|
320
|
+
# , group -- :: Eq a => [a] -> [[a]]
|
321
|
+
def group
|
322
|
+
warn "Method 'group' is not implemented yet." if $VERBOSE
|
323
|
+
return []
|
324
|
+
end
|
325
|
+
|
326
|
+
# , inits -- :: [a] -> [[a]]
|
327
|
+
def inits
|
328
|
+
warn "Method 'inits' is not implemented yet." if $VERBOSE
|
329
|
+
return []
|
330
|
+
end
|
331
|
+
|
332
|
+
# , tails -- :: [a] -> [[a]]
|
333
|
+
def tails
|
334
|
+
warn "Method 'tails' is not implemented yet." if $VERBOSE
|
335
|
+
return []
|
336
|
+
end
|
337
|
+
|
338
|
+
# -- ** Predicates
|
339
|
+
# , isPrefixOf -- :: (Eq a) => [a] -> [a] -> Bool
|
340
|
+
def is_prefix_of
|
341
|
+
warn "Method 'is_prefix_of' is not implemented yet." if $VERBOSE
|
342
|
+
return []
|
343
|
+
end
|
344
|
+
alias isPrefixOf is_prefix_of
|
345
|
+
|
346
|
+
# , isSuffixOf -- :: (Eq a) => [a] -> [a] -> Bool
|
347
|
+
def is_suffix_of
|
348
|
+
warn "Method 'is_suffix_of' is not implemented yet." if $VERBOSE
|
349
|
+
return []
|
350
|
+
end
|
351
|
+
alias isSuffixOf is_suffix_of
|
352
|
+
|
353
|
+
# -- * Searching lists
|
354
|
+
|
355
|
+
# -- ** Searching by equality
|
356
|
+
# , elem -- :: a -> [a] -> Bool
|
357
|
+
def elem
|
358
|
+
warn "Method 'elem' is not implemented yet." if $VERBOSE
|
359
|
+
return []
|
360
|
+
end
|
361
|
+
|
362
|
+
# , notElem -- :: a -> [a] -> Bool
|
363
|
+
def not_elem
|
364
|
+
warn "Method 'not_elem' is not implemented yet." if $VERBOSE
|
365
|
+
return []
|
366
|
+
end
|
367
|
+
alias notElem not_elem
|
368
|
+
|
369
|
+
# , lookup -- :: (Eq a) => a -> [(a,b)] -> Maybe b
|
370
|
+
def lookup
|
371
|
+
warn "Method 'lookup' is not implemented yet." if $VERBOSE
|
372
|
+
return []
|
373
|
+
end
|
374
|
+
|
375
|
+
# -- ** Searching with a predicate
|
376
|
+
# , find -- :: (a -> Bool) -> [a] -> Maybe a
|
377
|
+
# Implemented by Array
|
378
|
+
|
379
|
+
# , filter -- :: (a -> Bool) -> [a] -> [a]
|
380
|
+
def filter
|
381
|
+
warn "Method 'filter' is not implemented yet." if $VERBOSE
|
382
|
+
return []
|
383
|
+
end
|
384
|
+
|
385
|
+
# , partition -- :: (a -> Bool) -> [a] -> ([a], [a])
|
386
|
+
# Implemented by Array
|
387
|
+
|
388
|
+
|
389
|
+
# -- * Indexing lists
|
390
|
+
# -- | These functions treat a list @xs@ as a indexed collection,
|
391
|
+
# -- with indices ranging from 0 to @'length' xs - 1@.
|
392
|
+
|
393
|
+
# , (!!) -- :: [a] -> Int -> a
|
394
|
+
# Don't know how to implement it in Ruby
|
395
|
+
|
396
|
+
|
397
|
+
# , elemIndex -- :: (Eq a) => a -> [a] -> Maybe Int
|
398
|
+
def elem_index
|
399
|
+
warn "Method 'elem_index' is not implemented yet." if $VERBOSE
|
400
|
+
return []
|
401
|
+
end
|
402
|
+
alias elemIndex elem_index
|
403
|
+
|
404
|
+
# , elemIndices -- :: (Eq a) => a -> [a] -> [Int]
|
405
|
+
def elem_indices
|
406
|
+
warn "Method 'elem_indices' is not implemented yet." if $VERBOSE
|
407
|
+
return []
|
408
|
+
end
|
409
|
+
alias elemIndices elem_indices
|
410
|
+
|
411
|
+
# , findIndex -- :: (a -> Bool) -> [a] -> Maybe Int
|
412
|
+
def find_index
|
413
|
+
warn "Method 'find_index' is not implemented yet." if $VERBOSE
|
414
|
+
return []
|
415
|
+
end
|
416
|
+
alias findIndex find_index
|
417
|
+
|
418
|
+
# , findIndices -- :: (a -> Bool) -> [a] -> [Int]
|
419
|
+
def find_indices
|
420
|
+
warn "Method 'find_indices' is not implemented yet." if $VERBOSE
|
421
|
+
return []
|
422
|
+
end
|
423
|
+
alias findIndices find_indices
|
424
|
+
|
425
|
+
|
426
|
+
# -- * Zipping and unzipping lists
|
427
|
+
|
428
|
+
# , zip -- :: [a] -> [b] -> [(a,b)]
|
429
|
+
# Implemented by Array
|
430
|
+
|
431
|
+
# , zip3
|
432
|
+
def zip3
|
433
|
+
warn "Method 'zip3' is not implemented yet." if $VERBOSE
|
434
|
+
return []
|
435
|
+
end
|
436
|
+
|
437
|
+
# , zip4, zip5, zip6, zip7
|
438
|
+
def zip4
|
439
|
+
warn "Method 'zip4' is not implemented yet." if $VERBOSE
|
440
|
+
return []
|
441
|
+
end
|
442
|
+
|
443
|
+
|
444
|
+
# , zipWith -- :: (a -> b -> c) -> [a] -> [b] -> [c]
|
445
|
+
def zip_with
|
446
|
+
warn "Method 'zip_with' is not implemented yet." if $VERBOSE
|
447
|
+
return []
|
448
|
+
end
|
449
|
+
alias zipWith zip_with
|
450
|
+
|
451
|
+
# , zipWith3
|
452
|
+
def zip_with3
|
453
|
+
warn "Method 'zip_with3' is not implemented yet." if $VERBOSE
|
454
|
+
return []
|
455
|
+
end
|
456
|
+
alias zipWith3 zip_with3
|
457
|
+
|
458
|
+
# , zipWith4, zipWith5, zipWith6, zipWith7
|
459
|
+
def zip_with4
|
460
|
+
warn "Method 'zip_with4' is not implemented yet." if $VERBOSE
|
461
|
+
return []
|
462
|
+
end
|
463
|
+
alias zipWith4 zip_with4
|
464
|
+
|
465
|
+
|
466
|
+
# , unzip -- :: [(a,b)] -> ([a],[b])
|
467
|
+
def unzip
|
468
|
+
warn "Method 'unzip' is not implemented yet." if $VERBOSE
|
469
|
+
return []
|
470
|
+
end
|
471
|
+
|
472
|
+
# , unzip3
|
473
|
+
def unzip3
|
474
|
+
warn "Method 'unzip3' is not implemented yet." if $VERBOSE
|
475
|
+
return []
|
476
|
+
end
|
477
|
+
|
478
|
+
# , unzip4, unzip5, unzip6, unzip7
|
479
|
+
def unzip4
|
480
|
+
warn "Method 'unzip4' is not implemented yet." if $VERBOSE
|
481
|
+
return []
|
482
|
+
end
|
483
|
+
|
484
|
+
|
485
|
+
# -- * Special lists
|
486
|
+
|
487
|
+
# -- ** Functions on strings
|
488
|
+
# , lines -- :: String -> [String]
|
489
|
+
def lines
|
490
|
+
warn "Method 'lines' is not implemented yet." if $VERBOSE
|
491
|
+
return []
|
492
|
+
end
|
493
|
+
|
494
|
+
# , words -- :: String -> [String]
|
495
|
+
def words
|
496
|
+
warn "Method 'words' is not implemented yet." if $VERBOSE
|
497
|
+
return []
|
498
|
+
end
|
499
|
+
|
500
|
+
# , unlines -- :: [String] -> String
|
501
|
+
def unlines
|
502
|
+
warn "Method 'unlines' is not implemented yet." if $VERBOSE
|
503
|
+
return []
|
504
|
+
end
|
505
|
+
|
506
|
+
# , unwords -- :: [String] -> String
|
507
|
+
def unwords
|
508
|
+
warn "Method 'unwords' is not implemented yet." if $VERBOSE
|
509
|
+
return []
|
510
|
+
end
|
511
|
+
|
512
|
+
|
513
|
+
# -- ** \"Set\" operations
|
514
|
+
|
515
|
+
# , nub -- :: (Eq a) => [a] -> [a]
|
516
|
+
def nub
|
517
|
+
warn "Method 'nub' is not implemented yet." if $VERBOSE
|
518
|
+
return []
|
519
|
+
end
|
520
|
+
|
521
|
+
|
522
|
+
# , delete -- :: (Eq a) => a -> [a] -> [a]
|
523
|
+
# Implemented by Array but semantics is different
|
524
|
+
def delete(o)
|
525
|
+
warn "Method 'delete' is not implemented yet." if $VERBOSE
|
526
|
+
return []
|
527
|
+
end
|
528
|
+
|
529
|
+
|
530
|
+
# , (\\) -- :: (Eq a) => [a] -> [a] -> [a]
|
531
|
+
# Don't know how to implement it in Ruby
|
532
|
+
|
533
|
+
|
534
|
+
# , union -- :: (Eq a) => [a] -> [a] -> [a]
|
535
|
+
def union
|
536
|
+
warn "Method 'union' is not implemented yet." if $VERBOSE
|
537
|
+
return []
|
538
|
+
end
|
539
|
+
|
540
|
+
# , intersect -- :: (Eq a) => [a] -> [a] -> [a]
|
541
|
+
def intersect
|
542
|
+
warn "Method 'intersect' is not implemented yet." if $VERBOSE
|
543
|
+
return []
|
544
|
+
end
|
545
|
+
|
546
|
+
|
547
|
+
# -- ** Ordered lists
|
548
|
+
# , sort -- :: (Ord a) => [a] -> [a]
|
549
|
+
# Implemented by Array
|
550
|
+
|
551
|
+
# , insert -- :: (Ord a) => a -> [a] -> [a]
|
552
|
+
# Implemented by Array but semantics is different
|
553
|
+
def insert(o)
|
554
|
+
warn "Method 'insert' is not implemented yet." if $VERBOSE
|
555
|
+
return []
|
556
|
+
end
|
557
|
+
|
558
|
+
|
559
|
+
# def functional_fold(st, &op)
|
560
|
+
# f = proc { |s, a|
|
561
|
+
# if a.empty? then
|
562
|
+
# proc { s }
|
563
|
+
# else
|
564
|
+
# f.call(op.call(s, a[0]), a.slice(1, a.length-1))
|
565
|
+
# end
|
566
|
+
# }
|
567
|
+
# f.call(st, self)
|
568
|
+
# end
|
569
|
+
|
570
|
+
end # List
|
571
|
+
|
572
|
+
end # Prelude
|