class Obfusk::List

Lazy List

Public Class Methods

mreturn(x) click to toggle source

Monad

# File lib/obfusk/list.rb, line 236
def self.mreturn(x)
  Cons x, Nil()
end

Public Instance Methods

[](i) click to toggle source

element at index

# 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
_() click to toggle source

pretend to be lazy (so we don’t need Obfusk.eager)

# File lib/obfusk/list.rb, line 72
def _
  self
end
_compare_data(rhs) click to toggle source
# 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) click to toggle source
# File lib/obfusk/list.rb, line 45
def _eq_data(rhs)
   match  Nil:  -> (_) { true },
          Cons: -> (_) { [head,tail] == [rhs.head,rhs.tail] }
end
append(ys) click to toggle source

append two lists

# File lib/obfusk/list.rb, line 127
def append(ys)
  match Nil:  -> (_) { ys._ },
        Cons: -> (_) { Cons(head) { tail.append ys } }
end
chain(m,*a,&b) click to toggle source

pretend to be lazy (see _)

# File lib/obfusk/list.rb, line 77
def chain(m,*a,&b)
  ::Obfusk.lazy { public_send(m,*a,&b) }
end
concat() click to toggle source

concatenate a list of lists

# File lib/obfusk/list.rb, line 164
def concat
  foldr(Nil()) { |x,ys| x.append ys }
end
each(&b) click to toggle source

# 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
empty?()
Alias for: null
filter(p = nil, &b) click to toggle source

the list of those elements that satisfy the predicate

# 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) click to toggle source

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:

“‘haskell 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.

# 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() click to toggle source

length

# File lib/obfusk/list.rb, line 108
def length
  n = 0; each { n += 1 }; n
end
map(f = nil, &b) click to toggle source

the list obtained by applying a function (or block) to each element

# 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() click to toggle source

empty?

# File lib/obfusk/list.rb, line 113
def null
  match Nil: -> (_) { true }, Cons: -> (_) { false }
end
Also aliased as: null?, empty?
null?()
Alias for: null
take(n) click to toggle source

the prefix of length n (or the list itself if n > length)

# 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() click to toggle source
# File lib/obfusk/list.rb, line 67
def to_a
  each.to_a
end
to_s() click to toggle source
# 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) click to toggle source

combine parallel elements of two lists using a binary operator

# 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