Class: StreamTransducer

Inherits:
Object show all
Defined in:
lib/raskell/streams.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ StreamTransducer

Returns a new instance of StreamTransducer.



326
327
328
329
330
# File 'lib/raskell/streams.rb', line 326

def initialize(options={})
  @before_function = options['before']
  @after_function = options['after']
  @inside_function = options['inside']
end

Instance Attribute Details

#after_functionObject

Returns the value of attribute after_function.



332
333
334
# File 'lib/raskell/streams.rb', line 332

def after_function
  @after_function
end

#before_functionObject

Returns the value of attribute before_function.



332
333
334
# File 'lib/raskell/streams.rb', line 332

def before_function
  @before_function
end

#inside_functionObject

Returns the value of attribute inside_function.



332
333
334
# File 'lib/raskell/streams.rb', line 332

def inside_function
  @inside_function
end

Class Method Details

.new(options = {}) ⇒ Object



334
335
336
337
338
339
340
# File 'lib/raskell/streams.rb', line 334

def self.new(options={})
  if options['inside'] && options['inside'].class != Identity
    options['before'] && options['after'] ? ->(x) { self.standard_new(options).(x) } : self.standard_new(options)
  else
    ->(x) { self.standard_new(options).(x) }
  end
end

Instance Method Details

#*(lamb) ⇒ Object



404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/raskell/streams.rb', line 404

def *(lamb)
  if lamb.kind_of?(Identity)
    self
  elsif [ToStream, StreamTransducer].include?(lamb.class)
    ## then fuse away the streams by just making this the Identity.new function
    self.fuse(lamb, self)
  else
    self.class.new({ 'before' => (self.before_function || Identity.new) * lamb ,
                     'inside' => self.inside_function,
                     'after' => self.after_function})
  end
end

#+(stream_transducer) ⇒ Object



344
345
346
347
348
349
350
351
352
353
# File 'lib/raskell/streams.rb', line 344

def +(stream_transducer)
  ##TODO handle case where before function and after functions exist
  if stream_transducer.kind_of?(StreamTransducer) && !stream_transducer.before_function && !stream_transducer.after_function && !self.before_function && !self.after_function
    StreamTransducer.new({
      'inside' => self.inside_function + stream_transducer.inside_function
    })
  else
    raise "#{stream_transducer.class} should be of class StreamTransducer to be combined via + with another StreamTransducer"
  end
end

#<=(val) ⇒ Object



430
431
432
433
# File 'lib/raskell/streams.rb', line 430

def <=(val)
  # feed data from the right
  self.(val.())
end

#>=(lamb) ⇒ Object



435
436
437
438
# File 'lib/raskell/streams.rb', line 435

def >=(lamb)
  # feed data from the left, assuming I am a wrapped Object of some sort
  lamb.(self.())
end

#call(arg) ⇒ Object



362
363
364
365
366
367
368
369
# File 'lib/raskell/streams.rb', line 362

def call(arg)
  before = self.before_function || Identity.new
  after = self.after_function || Identity.new
  after <= (F.from_stream * ->(stream) { 
    next_fn = self.inside_function * stream.next_item_function 
    Stream.new(next_fn, stream)
  } <= F.to_stream.(before.(arg)))
end

#fuse(before_converter, after_converter) ⇒ Object



400
401
402
# File 'lib/raskell/streams.rb', line 400

def fuse(before_converter, after_converter)
  before_converter.join(after_converter)
end

#join(after) ⇒ Object



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/raskell/streams.rb', line 371

def join(after)

  ## to = StreamTransducer, from = FromStream
  ## to = StreamTransducer, from = ToStream
  ## to = StreamTransducer, from = StreamTransducer
  before = self
  if after.class == before.class && !after.before_function && !before.after_function
    before.class.new({
      'before' => before.before_function,
      'inside' => after.inside_function * before.inside_function,
      'after' => after.after_function
    })
  elsif [ToStream,FromStream].include?(after.class) && !after.before_function && !before.after_function ## TODO TOMORROW figure this otu
    ## if i am a transducer and have no after, and from has no before
    ## then I cleanly merge with from and make a new transducer
    ## if i have an after, then I produce a lambda?
    ## NEXT STEP is to make a buuunch of test cases for all of this transducer/from/to merge stuff
    ## and then keep implementing until they all pass
    ## then build
    StreamTransducer.new({
      'before' =>  before.before_function,
      'inside' => before.inside_function,
      'after' => after.after_function
    })
  else
    ->(xs) { after.(before.(xs)) }
  end
end

#kind_of?(clazz) ⇒ Boolean

Returns:



357
358
359
# File 'lib/raskell/streams.rb', line 357

def kind_of?(clazz)
  clazz == Proc || standard_kind_of?(clazz)
end

#standard_kind_of?Object



356
# File 'lib/raskell/streams.rb', line 356

alias_method :standard_kind_of?, :kind_of?

#|(lamb) ⇒ Object



417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/raskell/streams.rb', line 417

def |(lamb)
  if lamb.kind_of?(Identity)
    self
  elsif [FromStream, ToStream, StreamTransducer].include?(lamb.class)
    ## then fuse away the streams by just making this the Identity.new function
    self.fuse(self, lamb)
  else
    self.class.new({ 'before' => self.before_function,
                     'inside' => self.inside_function,
                     'after' => (self.after_function || Identity.new) | lamb })
  end
end