# --------------------------------------------------------------------------- # # Seq Role # --------------------------------------------------------------------------- # # - An Immutable Sequence role # --------------------------------------------------------------------------- # ^Seq := ^Role.new({}); ^Seq.set_name('Sequence'); ^Seq.set_version('0.0.1'); ^Seq.set_authority('url:pugscode.org'); # --------------------------------------------------------------------------- # # Methods dependent upon the repr type, and so need to be defined ^Seq.add_method('head', -> { nil }); ^Seq.add_method('tail', -> { nil }); # --------------------------------------------------------------------------- # # methods not dependent upon the repr type, so we can implement in the role ^Seq.add_method('is_empty', -> { self.head()`is_nil(); }); ^Seq.add_method('length', -> { -> $list, $acc { &redo := &?SUB; $list.is_empty()`if_else( -> { $acc }, -> { &redo`($list.tail(), $acc`increment()) } ); }`(self, 0); }); ^Seq.add_method('reverse', -> { -> $list, @acc { &redo := &?SUB; $list.is_empty()`if_else( -> { $?CLASS.new(@acc) }, -> { &redo`($list.tail(), [ $list.head() ]`concat(@acc)) } ); }`(self.tail(), [ self.head() ]); }); ^Seq.add_method('apply', -> &code { -> $list, @acc { &redo := &?SUB; $list.is_empty()`if_else( -> { $?CLASS.new(@acc) }, -> { &redo`($list.tail(), @acc`push(&func`($list.head()))) } ); }`(self, []); }); ^Seq.add_method('filter', -> &code { -> $list, @acc { &redo := &?SUB; $list.is_empty()`if_else( -> { $?CLASS.new(@acc) }, -> { &func`($list.head())`as_bit()`if_else( -> { &redo`($list.tail(), @acc`push($elem)) }, -> { &redo`($list.tail(), @acc) } ); } ); }`(self, []); }); ^Seq.add_method('reduce', -> &func { -> $list, $acc { &redo := &?SUB; $list.is_empty()`if_else( -> { $acc }, -> { &redo`($list.tail(), &func`($acc, $list.head())) } ); }`(self.tail(), self.head()); });