Module: System::Collections::StreamLambdas
Instance Method Summary collapse
- #append ⇒ Object
- #cartesian_product ⇒ Object
- #concat ⇒ Object
- #cons ⇒ Object
- #contains? ⇒ Boolean
- #contains_slice? ⇒ Boolean
- #continuous_subsequences ⇒ Object
- #difference ⇒ Object
- #does_not_contain? ⇒ Boolean
- #empty ⇒ Object
- #empty? ⇒ Boolean
- #enconcat ⇒ Object
- #ends_with? ⇒ Boolean
- #final ⇒ Object
- #first ⇒ Object
- #first_index_of ⇒ Object
- #group ⇒ Object
- #head ⇒ Object
- #init ⇒ Object
- #initial ⇒ Object
- #inits ⇒ Object
-
#intercalate ⇒ Object
you can undo this with % n, where n is the number of streams.
- #interleave ⇒ Object
- #intersect ⇒ Object
- #intersperse ⇒ Object
-
#last ⇒ Object
stream functions.
- #last_index_of ⇒ Object
- #length ⇒ Object
- #length_at_least ⇒ Object
- #null? ⇒ Boolean
- #partition_at ⇒ Object
- #prefix ⇒ Object
- #prefixes ⇒ Object
-
#quicksort ⇒ Object
continuous subsequences is useful for exact inside sequence matching a la find in sublime.
- #replace ⇒ Object
- #rest ⇒ Object
- #reverse ⇒ Object
- #rotate ⇒ Object
- #snoc ⇒ Object
- #starts_with? ⇒ Boolean
- #subsequences ⇒ Object
- #suffix ⇒ Object
- #suffixes ⇒ Object
- #tail ⇒ Object
- #tails ⇒ Object
- #transpose ⇒ Object
- #uncons ⇒ Object
- #union ⇒ Object
- #unsnoc ⇒ Object
- #unzip ⇒ Object
- #window ⇒ Object
- #wrap ⇒ Object
- #zip ⇒ Object
- #zip_with_index ⇒ Object
Instance Method Details
#append ⇒ Object
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
# File 'lib/raskell/f.rb', line 651 def append @@append||= ->(left_stream) { ->(right_stream) { left_next_fn = ->(stream) { next_el = stream.next_item if next_el == [:done] [:skip, right_stream] elsif next_el.first == :skip [:skip, Stream.new(left_next_fn, next_el.last)] elsif next_el.first == :yield [next_el.first, next_el[1], Stream.new(left_next_fn, next_el.last)] else raise "#{next_el.inspect} is not a valid stream state!" end } Stream.new(left_next_fn, left_stream) } * to_stream } * to_stream end |
#cartesian_product ⇒ Object
886 887 888 889 890 891 892 |
# File 'lib/raskell/f.rb', line 886 def cartesian_product @@cartesian_product||= ->(xs) { ->(ys) { flatmap.(->(x) { map.(->(y) { [x,y] }, ys) }, xs) } * to_stream } * to_stream end |
#concat ⇒ Object
673 674 675 |
# File 'lib/raskell/f.rb', line 673 def concat @@concat||= flatmap.(to_stream) end |
#cons ⇒ Object
573 574 575 576 577 578 579 |
# File 'lib/raskell/f.rb', line 573 def cons @@cons||= ->(el) { ->(stream) { Stream.new(->(x) { [:yield, el, stream] } , Nothing) } * to_stream } end |
#contains? ⇒ Boolean
837 838 839 |
# File 'lib/raskell/f.rb', line 837 def contains? @@contains_p||= ->(el) { F.not * F.equal.(Nothing) * find_where.(equals.(el)) } end |
#contains_slice? ⇒ Boolean
845 846 847 |
# File 'lib/raskell/f.rb', line 845 def contains_slice? @@contains_slice_p||= ->(slice) { any?.(starts_with.(slice)) * tails } end |
#continuous_subsequences ⇒ Object
919 920 921 |
# File 'lib/raskell/f.rb', line 919 def continuous_subsequences @@continuous_subsequences||= filter.(F.not * empty?) * flatmap.(prefixes) * suffixes end |
#difference ⇒ Object
877 878 879 880 881 882 883 884 |
# File 'lib/raskell/f.rb', line 877 def difference @@difference||= ->(xs) { ->(ys) { to_remove = to_set.(ys) filter.(->(x) { !ys.include?(x)}) << xs } * to_stream } * to_stream end |
#does_not_contain? ⇒ Boolean
841 842 843 |
# File 'lib/raskell/f.rb', line 841 def does_not_contain? @@does_not_contain_p||= ->(el) { F.equal.(Nothing) * find_where.(equals.(el)) } end |
#empty ⇒ Object
562 563 564 |
# File 'lib/raskell/f.rb', line 562 def empty @@empty||= Stream.new(->(x) { [:done] }, Nothing) end |
#empty? ⇒ Boolean
554 555 556 |
# File 'lib/raskell/f.rb', line 554 def empty? @@empty_p||= F.equal.(empty) end |
#enconcat ⇒ Object
677 678 679 |
# File 'lib/raskell/f.rb', line 677 def enconcat @@enconcat||= ->(left_stream, el) { append.(left_stream.to_stream) * cons.(el) * to_stream } end |
#ends_with? ⇒ Boolean
829 830 831 |
# File 'lib/raskell/f.rb', line 829 def ends_with? @@ends_with||= ->(slice) { F.equal.(slice) * drop_except.(length.(slice)) } end |
#final ⇒ Object
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 |
# File 'lib/raskell/f.rb', line 699 def final @@final||= -> (stream) { next_fn = ->(state) { prev_step = state.first strm = state.last raise("Must have at least one item inside of the stream!") if prev_step == [:done] next_item = strm.next_item if prev_step.first == :skip [:skip, Stream.new(next_fn, [next_item, next_item.last])] elsif next_item == [:done] [:yield, prev_step[1], empty] elsif next_item.first == :yield [:skip, Stream.new(next_fn, [next_item, next_item.last])] elsif next_item.first == :skip [:skip, Stream.new(next_fn, [prev_step, next_item.last])] else raise "#{next_item} is a malformed stream result" end } next_item = stream.next_item Stream.new(next_fn, [next_item, next_item.last]) } * to_stream end |
#first ⇒ Object
582 583 584 585 586 587 588 589 590 |
# File 'lib/raskell/f.rb', line 582 def first @@first||= -> (stream) { ## should offer an equivalent that returns a stream with a single element next_item = stream.next_item while next_item.first == :skip next_item = next_item.last.next_item end next_item.first == :yield ? next_item[1] : Nothing } * to_stream end |
#first_index_of ⇒ Object
857 858 859 |
# File 'lib/raskell/f.rb', line 857 def first_index_of @@first_index_of||= ->(x) { first_index_where.( F.equal.(x) ) } end |
#group ⇒ Object
936 937 938 |
# File 'lib/raskell/f.rb', line 936 def group @@group||= ->(xs) { group_by.(id) } end |
#head ⇒ Object
813 814 815 |
# File 'lib/raskell/f.rb', line 813 def head @@head||= first end |
#init ⇒ Object
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
# File 'lib/raskell/f.rb', line 628 def init @@init||= ->(stream) { next_fn = ->(state) { strm = state.last next_item = strm.next_item if next_item == [:done] && state.first == Nothing raise "init requires a stream length of at least 1" elsif next_item == [:done] [:done] elsif next_item.first == :skip [:skip, Stream.new(next_fn, [state.first, next_item.last])] elsif next_item.first == :yield && state.first == Nothing [:skip, Stream.new(next_fn, [next_item[1], next_item.last])] elsif next_item.first == :yield [:yield, state.first, Stream.new(next_fn, [next_item[1], next_item.last])] else raise "#{next_item} is a malformed stream response" end } Stream.new(next_fn, [Nothing, stream]) } * to_stream end |
#initial ⇒ Object
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
# File 'lib/raskell/f.rb', line 681 def initial @@initial||= ->(stream) { next_fn = ->(strm) { next_item = strm.next_item if next_item.first == :done raise "Must have at least one item inside of the stream!" elsif next_item.first == :yield [:yield, next_item[1], empty] elsif next_item.first == :skip [:skip, next_item.last] else raise("#{next_item} is a malformed stream response!") end } Stream.new(next_fn, stream) } end |
#inits ⇒ Object
817 818 819 |
# File 'lib/raskell/f.rb', line 817 def inits @@inits||= prefixes end |
#intercalate ⇒ Object
you can undo this with % n, where n is the number of streams
733 734 735 |
# File 'lib/raskell/f.rb', line 733 def intercalate @@intercalate||= ->(xs, xss) { concat.intersperse.(xs, xss) } end |
#interleave ⇒ Object
729 730 731 |
# File 'lib/raskell/f.rb', line 729 def interleave @@interleave||= ->(xs, *ys) { ys.length > 0 ? (concat * zip).(*([xs]+ys)) : ->(zs, *ys) { concat << zip.(*([xs,zs]+ys)) } } end |
#intersect ⇒ Object
869 870 871 872 873 874 875 |
# File 'lib/raskell/f.rb', line 869 def intersect @@intersect||= ->(xs) { ->(ys) { to_stream << (to_set.(xs) & to_set.(ys)) } * to_stream } * to_stream end |
#intersperse ⇒ Object
833 834 835 |
# File 'lib/raskell/f.rb', line 833 def intersperse @@intersperse||= ->(x, xs) { rest * flatmap.(->(y) { [x, y].to_stream }) << xs.to_stream } end |
#last ⇒ Object
stream functions
761 762 763 |
# File 'lib/raskell/f.rb', line 761 def last @@last||= first * final end |
#last_index_of ⇒ Object
853 854 855 |
# File 'lib/raskell/f.rb', line 853 def last_index_of @@last_index_of||= ->(x) { last_index_where.(F.equal.(x)) } end |
#length ⇒ Object
777 778 779 |
# File 'lib/raskell/f.rb', line 777 def length @@length||= foldl.(inc, 0) end |
#length_at_least ⇒ Object
781 782 783 |
# File 'lib/raskell/f.rb', line 781 def length_at_least @@length_at_least||= ->(n) { ->(x) { x != Nothing } * find_where.(equals.(n)) * scanl.(inc, 0) } end |
#null? ⇒ Boolean
558 559 560 |
# File 'lib/raskell/f.rb', line 558 def null? @@null_p||= F.equal.(empty) end |
#partition_at ⇒ Object
849 850 851 |
# File 'lib/raskell/f.rb', line 849 def partition_at @@partition_at||= ->(n) { take.(n) + drop.(n) } end |
#prefix ⇒ Object
805 806 807 |
# File 'lib/raskell/f.rb', line 805 def prefix @@prefix||= init end |
#prefixes ⇒ Object
756 757 758 |
# File 'lib/raskell/f.rb', line 756 def prefixes @@prefixes||= foldr.(->(el, acc) { cons.(empty, map.(cons.(el), acc)) }, wrap.(empty)) end |
#quicksort ⇒ Object
continuous subsequences is useful for exact inside sequence matching a la find in sublime
924 925 926 927 928 929 930 931 932 933 934 |
# File 'lib/raskell/f.rb', line 924 def quicksort ->(xs) { if empty?.(xs) empty else pivot = head.(xs) partitions = (F.map.(self.quicksort) * partition_by.(F.is_lte.(pivot)) << tail.(xs)).to_a append.(partitions[0],cons.(pivot, partitions[1])) end } * to_stream ### if only this wasn't infinitely recursing... end |
#replace ⇒ Object
785 786 787 |
# File 'lib/raskell/f.rb', line 785 def replace @@replace||= ->(to_replace, to_replace_with) {map.(->(x) { x == to_replace ? to_replace_with : x })} end |
#rest ⇒ Object
592 593 594 595 596 597 |
# File 'lib/raskell/f.rb', line 592 def rest @@rest||= -> (stream) { next_item = stream.next_item next_item == [:done] ? Nothing : next_item.last } * to_stream end |
#reverse ⇒ Object
773 774 775 |
# File 'lib/raskell/f.rb', line 773 def reverse @@reverse||= foldl.(->(acc, el) { cons.(el, acc) }, []) ## or foldr.(->(el,acc) { snoc.(acc, el) } end |
#rotate ⇒ Object
724 725 726 |
# File 'lib/raskell/f.rb', line 724 def rotate @@rotate||= ->(s) { append.(tail.(s), initial.(s)) } end |
#snoc ⇒ Object
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'lib/raskell/f.rb', line 599 def snoc @@snoc||= ->(el) { ->(stream) { # next_fn = step.(->(stream) { # next_item = stream.next_item # next_item == [:done] ? wrap.(el) : next_item.last # }, # ->(stream) { # next_item = stream.next_item # next_item.first == :skip ? Nothing : next_item[1] # }) next_fn = ->(s) { next_item = s.next_item if next_item == [:done] [:skip, wrap.(el)] elsif next_item.first == :skip [:skip, Stream.new(next_fn, next_item.last)] elsif next_item.first == :yield [:yield, next_item[1], Stream.new(next_fn, next_item.last)] else raise "#{next_item} is a malformed stream result" end } Stream.new(next_fn, stream) } * to_stream } end |
#starts_with? ⇒ Boolean
825 826 827 |
# File 'lib/raskell/f.rb', line 825 def starts_with? @@starts_with||= ->(prefix, stream) { F.ands << zip_with.(equals, prefix, stream) } end |
#subsequences ⇒ Object
906 907 908 909 910 |
# File 'lib/raskell/f.rb', line 906 def subsequences @@subsequences||= ->() { ## Using the applicative instance for <**>, which is ^ in Raskell subs = ->(ys) { ys == empty ? wrap.(empty) : subs.(rest.(ys)) ^ [F.id, F.cons.(first.(ys))].to_stream } }.() #wrap.(empty) end |
#suffix ⇒ Object
809 810 811 |
# File 'lib/raskell/f.rb', line 809 def suffix @@suffix||= rest end |
#suffixes ⇒ Object
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
# File 'lib/raskell/f.rb', line 737 def suffixes @@suffixes||= ->(stream) { next_fn = ->(strm) { next_item = strm.next_item if next_item.first == :done [:yield, strm, empty] elsif next_item.first == :yield [:yield, strm, Stream.new(next_fn, next_item.last)] elsif next_item.first == :skip [:skip, Stream.new(next_fn, next_item.last)] else raise("#{next_item} is a malformed stream response!") end } Stream.new(next_fn, stream) } * to_stream end |
#tail ⇒ Object
801 802 803 |
# File 'lib/raskell/f.rb', line 801 def tail @@tail||= rest end |
#tails ⇒ Object
821 822 823 |
# File 'lib/raskell/f.rb', line 821 def tails @@tails||= suffixes end |
#transpose ⇒ Object
797 798 799 |
# File 'lib/raskell/f.rb', line 797 def transpose @@transpose||= ->(stream_of_streams) { zip.( *(stream_of_streams.to_stream) ) } end |
#uncons ⇒ Object
765 766 767 |
# File 'lib/raskell/f.rb', line 765 def uncons @@uncons||= ->(s) { append(first.(l), wrap(rest.(l))) } * to_stream end |
#union ⇒ Object
861 862 863 864 865 866 867 |
# File 'lib/raskell/f.rb', line 861 def union @@union||= ->(xs) { ->(ys) { to_stream * to_set << append.(xs, ys) } * to_stream } * to_stream end |
#unsnoc ⇒ Object
769 770 771 |
# File 'lib/raskell/f.rb', line 769 def unsnoc @@unsnoc||= ->(s) { append(wrap(init.(s)), last.(s)) } * to_stream end |
#unzip ⇒ Object
894 895 896 897 898 |
# File 'lib/raskell/f.rb', line 894 def unzip @@unzip||= ->(xs) { map.(first) + map.(last) << xs } * to_stream end |
#window ⇒ Object
900 901 902 903 904 |
# File 'lib/raskell/f.rb', line 900 def window @@window||= ->(n) { map.(take.(n)) * suffixes } end |
#wrap ⇒ Object
566 567 568 569 570 571 |
# File 'lib/raskell/f.rb', line 566 def wrap @@wrap||= ->(x) { next_fn = ->(bool) { bool ? [:yield, x, Stream.new(next_fn, false)] : [:done]} Stream.new(next_fn, true) } end |
#zip ⇒ Object
789 790 791 |
# File 'lib/raskell/f.rb', line 789 def zip @@zip||= zip_with.(list) end |
#zip_with_index ⇒ Object
793 794 795 |
# File 'lib/raskell/f.rb', line 793 def zip_with_index @@zip_with_index||= F.zip_with.(F.list).(F.range.(0, F.infinity)) end |