-module(word_split). -export([words/1, to_list/1]). %%-include_lib("src/ebb_flow.erl"). % data WordState = {chunk, S} | {segment, L, C, R} nil() -> nil. singleton(S) -> {single, S}. conc(A, B) -> {conc, A, B}. to_list(nil) -> []; to_list({single, S}) -> [S]; to_list({conc, A, B}) -> to_list(A) ++ to_list(B). maybe_word("") -> nil(); maybe_word(S) -> singleton(S). process_char(C) -> case lists:member(C, " \t\n\f\l") of true -> {segment, "", nil(), ""}; false -> {chunk, [C]} end. combine({chunk, S1}, {chunk, S2}) -> {chunk, S1 ++ S2}; combine({chunk, S}, {segment, L, C, R}) -> {segment, S ++ L, C, R}; combine({segment, L, C, R}, {chunk, S}) -> {segment, L, C, R ++ S}; combine({segment, L1, C1, R1}, {segment, L2, C2, R2}) -> {segment, L1, conc(C1, conc(maybe_word(R1 ++ L2), C2)), R2}. head([X|_]) -> X. words(Str) -> T = ebb_flow:map_reduce(fun process_char/1, fun combine/2, Str), case head(ebb_run:run_linear(T)) of {chunk, S} -> maybe_word(S); {segment, L, C, R} -> conc(maybe_word(L), conc(C, maybe_word(R))); _ -> error end.