% mmc -O2 --optimise-higher-order --optimise-constant-propagation --no-common-struct -C string2 :- module string2. :- interface. :- func string2.length(string::in) = (int::uo) is det. :- func string2.foldr(func(character, T) = T, string, T) = T. :- pred string2.foldr(pred(character, T, T), string, T, T). :- mode string2.foldr(pred(in, in, out) is det, in, in, out) is det. :- pred string2.foldr_substring(pred(character, T, T), string, int, int, T, T). :- mode string2.foldr_substring(pred(in, in, out) is det, in, in, in, in, out) is det. %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% :- implementation. :- import_module int. %-----------------------------------------------------------------------------% string2.foldr(F, String, Acc0) = Acc :- Closure = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y)), string2.foldr(Closure, String, Acc0, Acc). string2.foldr(Closure, String, Acc0, Acc) :- string2.foldr_substring(Closure, String, 0, length(String), Acc0, Acc). string2.foldr_substring(Closure, String, Start0, Count0, Acc0, Acc) :- Start = max2(0, Start0), Count = min2(Count0, length(String) - Start), string2.foldr_substring_2(Closure, String, Start, Count, Acc0, Acc). :- pred string2.foldr_substring_2(pred(character, T, T), string, int, int, T, T). :- mode string2.foldr_substring_2(pred(in, in, out) is det, in, in, in, in, out) is det. string2.foldr_substring_2(Closure, String, I, Count, !Acc) :- ( 0 < Count -> Closure(string2.unsafe_index(String, I + Count - 1), !Acc), string2.foldr_substring_2(Closure, String, I, Count - 1, !Acc) ; true ). :- func string2.unsafe_index(string, int) = character. :- pragma foreign_proc("C", string2.unsafe_index(Str::in, Index::in) = (Ch::out), [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail, does_not_affect_liveness], " Ch = Str[Index]; "). :- pragma foreign_proc("C", string2.length(Str::in) = (Length::uo), [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail, does_not_affect_liveness], " Length = strlen(Str); "). :- func max2(int, int) = int. max2(X_4, Y_5) = Max_6 :- (if int.(X_4 > Y_5) then Max_6 = X_4 else Max_6 = Y_5 ). :- func min2(int, int) = int. min2(X_4, Y_5) = Min_6 :- (if int.(X_4 < Y_5) then Min_6 = X_4 else Min_6 = Y_5 ).