// // in? // in?(elem, seq) = find(elem, seq) != end(seq); // // trim, trimBegin, trimEnd // [T | Sequence?(T)] trim(pred, seq:T) = T(trimSlice(pred, seq)); [T | Sequence?(T)] trimBegin(pred, seq:T) = T(trimBeginSlice(pred, seq)); [T | Sequence?(T)] trimEnd(pred, seq:T) = T(trimEndSlice(pred, seq)); overload trim(pred, seq:StringConstant) = String(trimSlice(pred, seq)); overload trimBegin(pred, seq:StringConstant) = String(trimBeginSlice(pred, seq)); overload trimEnd(pred, seq:StringConstant) = String(trimEndSlice(pred, seq)); [T | String?(T)] overload trim(s:T, seq) = trim(lambda(x) { return in?(x,s); }, seq); [T | String?(T)] overload trimBegin(s:T, seq) = trimBegin(lambda(x) { return in?(x,s); }, seq); [T | String?(T)] overload trimEnd(s:T, seq) = trimEnd(lambda(x) { return in?(x,s); }, seq); // // trimSlice, trimBeginSlice, trimEndSlice // trimSlice(pred, seq) = trimBeginSlice(pred, trimEndSlice(pred, seq)); trimBeginSlice(pred, seq) { var i = 0; for (x in seq) { if (pred(x)) inc(i); else break; } return sliceFrom(seq, i); } trimEndSlice(pred, seq) { var i = 0; for (x in reverse(seq)) { if (pred(x)) inc(i); else break; } return sliceUpto(seq, size(seq) - i); } [T | String?(T)] overload trimSlice(s:T, seq) = trimSlice(lambda(x) { return in?(x,s); }, seq); [T | String?(T)] overload trimBeginSlice(s:T, seq) = trimBeginSlice(lambda(x) { return in?(x,s); }, seq); [T | String?(T)] overload trimEndSlice(s:T, seq) = trimEndSlice(lambda(x) { return in?(x,s); }, seq); // // beginsWith?, endsWith? // beginsWith?(x, seq) = sliceUpto(seq, size(x)) == x; endsWith?(x, seq) { if (size(seq) < size(x)) return false; return sliceFrom(seq, size(seq) - size(x)) == x; }