Module: System::Collections::StreamDropAndTakeLambdas

Extended by:
StreamDropAndTakeLambdas
Included in:
StreamDropAndTakeLambdas, F
Defined in:
lib/raskell/f.rb

Instance Method Summary collapse

Instance Method Details

#dropObject

there are so many of these I pulled them into their own



1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
# File 'lib/raskell/f.rb', line 1019

def drop
  @@drop||= ->(n) {
    raise("#{n} must be a positive number") if n < 0
    ->(stream) {
      next_fn = step.(->(state){
          next_item = state.last.next_item
          count = next_item.first == :skip || state.first == 0 ? state.first : state.first-1
          next_item == [:done] ? Nothing : [count, next_item.last]
        },
    ->(state) { 
          count = state.first
          next_item = state.last.next_item
          next_item.first == :yield && count == 0 ? next_item[1] : Nothing
        })
      Stream.new(next_fn, [n, stream])
    } * to_stream
  }
end

#drop_exceptObject



1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
# File 'lib/raskell/f.rb', line 1060

def drop_except
  @@drop_except||= ->(n) {
    raise("#{n} must be a positive number") if n < 0
    ->(stream) {
      next_fn = cstep.(
        ->(state) {
          strm = state.last
          accumulated_items = state.first
          next_el = strm.next_item
          accumulated_items = (state.first.length < n  ?  state.first  :  state.first[1..-1]) + [next_el[1]] if next_el.first == :yield
          next_el == [:done]  ?  accumulated_items.to_stream  :  Stream.new(next_fn, [accumulated_items, next_el.last])
        },
        ->(state) { Nothing }
      )
      Stream.new(next_fn, [[], stream])
    } * to_stream
  }
end

#drop_untilObject



1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
# File 'lib/raskell/f.rb', line 1151

def drop_until
  @@drop_until||= ->(fn) {
    raise("drop_while requires a function") unless fn.kind_of?(Proc)
    ->(stream) {
      next_fn = ->(state) {
          next_item = state.next_item
          tag = next_item.first
          val = next_item[1]
          next_strm = next_item.last
          if tag == :done
            [:done]
          elsif tag == :skip || (tag == :yield && !fn.(val))
            [:skip, Stream.new(next_fn, next_strm)]
          elsif tag == :yield
            [:yield, val, next_strm]
          else
            raise("#{next_item} is a malformed stream response!")
          end
      }
      Stream.new(next_fn, stream)
    } * to_stream
  }
end

#drop_whileObject



1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
# File 'lib/raskell/f.rb', line 1103

def drop_while
  @@drop_while||= ->(fn) {
    raise("drop_while requires a function") unless fn.kind_of?(Proc)
    ->(stream) {
      next_fn = ->(state) {
          next_item = state.next_item
          tag = next_item.first
          val = next_item[1]
          next_strm = next_item.last
          if tag == :done
            [:done]
          elsif tag == :skip || (tag == :yield && fn.(val))
            [:skip, Stream.new(next_fn, next_strm)]
          elsif tag == :yield
            [:yield, val, next_strm]
          else
            raise("#{next_item} is a malformed stream response!")
          end
      }
      Stream.new(next_fn, stream)
    } * to_stream
  }
end

#takeObject



1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
# File 'lib/raskell/f.rb', line 1038

def take
  @@take||= ->(n) {
    raise("#{n} must be a positive number") if n < 0
    ->(stream) {
      next_fn = step.(->(state){
          if state.first == 0
            Nothing
          else
            next_item = state.last.next_item
            count = next_item.first == :skip ? state.first : state.first-1
            next_item == [:done] ? Nothing : [count, next_item.last]
          end
        },
    ->(state) { 
          next_item = state.last.next_item
          next_item.first == :yield ? next_item[1] : Nothing
        })
      Stream.new(next_fn, [n, stream])
    } * to_stream
  }
end

#take_untilObject



1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
# File 'lib/raskell/f.rb', line 1127

def take_until
  @@take_until||= ->(fn) {
    raise("take_while requires a function") unless fn.kind_of?(Proc)
    ->(stream) {
      next_fn = ->(state) {
          next_item = state.next_item
          tag = next_item.first
          val = next_item[1]
          next_stream = next_item.last
          if tag == :done || (tag == :yield && fn.(val))
            [:done]
          elsif tag == :skip
            [:skip, Stream.new(next_fn, next_stream)]
          elsif tag == :yield
            [:yield, val, Stream.new(next_fn, next_stream)]
          else
            raise("#{next_item} is a malformed stream response!")
          end
      }
      Stream.new(next_fn, stream)
    } * to_stream
  }
end

#take_whileObject



1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
# File 'lib/raskell/f.rb', line 1079

def take_while
  @@take_while||= ->(fn) {
    raise("take_while requires a function") unless fn.kind_of?(Proc)
    ->(stream) {
      next_fn = ->(state) {
          next_item = state.next_item
          tag = next_item.first
          val = next_item[1]
          next_stream = next_item.last
          if tag == :done || (tag == :yield && !fn.(val))
            [:done]
          elsif tag == :skip
            [:skip, Stream.new(next_fn, next_stream)]
          elsif tag == :yield
            [:yield, val, Stream.new(next_fn, next_stream)]
          else
            raise("#{next_item} is a malformed stream response!")
          end
      }
      Stream.new(next_fn, stream)
    } * to_stream
  }
end