Class: Obfusk::List
- Inherits:
-
Object
- Object
- Obfusk::List
- Defined in:
- lib/obfusk/list.rb
Overview
Lazy List
Defined Under Namespace
Classes: Cons
Class Method Summary collapse
-
.mreturn(x) ⇒ Object
-- Monad --.
Instance Method Summary collapse
-
#[](i) ⇒ Object
element at index.
-
#_ ⇒ Object
pretend to be lazy (so we don't need Obfusk.eager).
- #_compare_data(rhs) ⇒ Object
- #_eq_data(rhs) ⇒ Object
-
#append(ys) ⇒ Object
append two lists.
-
#chain(m, *a, &b) ⇒ Object
pretend to be lazy (see _).
-
#concat ⇒ Object
concatenate a list of lists.
-
#each(&b) ⇒ Object
--.
-
#filter(p = nil, &b) ⇒ Object
the list of those elements that satisfy the predicate.
-
#foldr(z, f = nil, &b) ⇒ Object
foldr, applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:.
-
#length ⇒ Object
length.
-
#map(f = nil, &b) ⇒ Object
the list obtained by applying a function (or block) to each element.
-
#null ⇒ Object
(also: #null?, #empty?)
empty?.
-
#take(n) ⇒ Object
the prefix of length n (or the list itself if n > length).
- #to_a ⇒ Object
- #to_s ⇒ Object
-
#zipWith(ys, f = nil, &b) ⇒ Object
combine parallel elements of two lists using a binary operator.
Methods included from MonadPlus
Methods included from Monad
Methods included from ADT
#<=>, #==, #__adt_ctor__, #__adt_ctor_keys__, #__adt_ctor_name__, #__adt_data__, #clone, #eql?, included, #initialize, #inspect, #match
Class Method Details
.mreturn(x) ⇒ Object
-- Monad --
236 237 238 |
# File 'lib/obfusk/list.rb', line 236 def self.mreturn(x) Cons x, Nil() end |
Instance Method Details
#[](i) ⇒ Object
element at index
101 102 103 104 105 |
# File 'lib/obfusk/list.rb', line 101 def [](i) raise ArgumentError, 'negative index' if i < 0 j = 0; each { |x| return x if i == j; j += 1 } raise ArgumentError, 'index too large' end |
#_ ⇒ Object
pretend to be lazy (so we don't need Obfusk.eager)
72 73 74 |
# File 'lib/obfusk/list.rb', line 72 def _ self end |
#_compare_data(rhs) ⇒ Object
50 51 52 53 |
# File 'lib/obfusk/list.rb', line 50 def _compare_data(rhs) match Nil: -> (_) { 0 }, Cons: -> (_) { [head,tail] <=> [rhs.head,rhs.tail] } end |
#_eq_data(rhs) ⇒ Object
45 46 47 48 |
# File 'lib/obfusk/list.rb', line 45 def _eq_data(rhs) match Nil: -> (_) { true }, Cons: -> (_) { [head,tail] == [rhs.head,rhs.tail] } end |
#append(ys) ⇒ Object
append two lists
127 128 129 130 |
# File 'lib/obfusk/list.rb', line 127 def append(ys) match Nil: -> (_) { ys._ }, Cons: -> (_) { Cons(head) { tail.append ys } } end |
#chain(m, *a, &b) ⇒ Object
pretend to be lazy (see _)
77 78 79 |
# File 'lib/obfusk/list.rb', line 77 def chain(m,*a,&b) ::Obfusk.lazy { public_send(m,*a,&b) } end |
#concat ⇒ Object
concatenate a list of lists
164 165 166 |
# File 'lib/obfusk/list.rb', line 164 def concat foldr(Nil()) { |x,ys| x.append ys } end |
#each(&b) ⇒ Object
--
57 58 59 60 |
# File 'lib/obfusk/list.rb', line 57 def each(&b) return enum_for :each unless b xs = self; while xs != Nil() do b[xs.head]; xs = xs.tail end end |
#filter(p = nil, &b) ⇒ Object
the list of those elements that satisfy the predicate
84 85 86 87 88 89 |
# File 'lib/obfusk/list.rb', line 84 def filter(p = nil, &b) g = p || b match Nil: -> (_) { Nil() }, Cons: -> (_) { g[head] ? Cons(head) { tail.filter(g) } : tail.filter(g) } end |
#foldr(z, f = nil, &b) ⇒ Object
foldr, applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:
foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)
NB: because ruby is not lazy, the secons argument of the binary operator is lazy and must be treated as such.
149 150 151 152 153 |
# File 'lib/obfusk/list.rb', line 149 def foldr(z, f = nil, &b) g = f || b match Nil: -> (_) { z }, Cons: -> (_) { g[head, tail.chain(:foldr, z, g)] } end |
#length ⇒ Object
length
108 109 110 |
# File 'lib/obfusk/list.rb', line 108 def length n = 0; each { n += 1 }; n end |
#map(f = nil, &b) ⇒ Object
the list obtained by applying a function (or block) to each element
92 93 94 95 96 |
# File 'lib/obfusk/list.rb', line 92 def map(f = nil, &b) g = f || b match Nil: -> (_) { Nil() }, Cons: -> (_) { Cons(g[head]) { tail.map g } } end |
#null ⇒ Object Also known as: null?, empty?
empty?
113 114 115 |
# File 'lib/obfusk/list.rb', line 113 def null match Nil: -> (_) { true }, Cons: -> (_) { false } end |
#take(n) ⇒ Object
the prefix of length n (or the list itself if n > length)
192 193 194 195 196 |
# File 'lib/obfusk/list.rb', line 192 def take(n) return Nil() if n <= 0 match Nil: -> (_) { Nil() }, Cons: -> (_) { Cons(head) { tail.take(n - 1) } } end |
#to_a ⇒ Object
67 68 69 |
# File 'lib/obfusk/list.rb', line 67 def to_a each.to_a end |
#to_s ⇒ Object
62 63 64 65 |
# File 'lib/obfusk/list.rb', line 62 def to_s *xs, x = self.class.name.split '::'; n = xs*'::' + '.' + x self == Nil() ? "<##{n}>" : "<##{n}(#{head},...)>" end |
#zipWith(ys, f = nil, &b) ⇒ Object
combine parallel elements of two lists using a binary operator
217 218 219 220 221 |
# File 'lib/obfusk/list.rb', line 217 def zipWith(ys, f = nil, &b) g = f || b self == Nil() || ys._ == Nil() ? Nil() : Cons(g[head, ys._.head]) { tail.zipWith(ys._.tail, g) } end |