# Generated by Snowball.Generator — do not edit by hand. defmodule Text.Stemmer.Stemmers.Spanish do @moduledoc """ Snowball stemmer for spanish. Generated from the canonical Snowball algorithm source. """ alias Snowball.Runtime alias Snowball.Grouping # Groupings @g_v Grouping.from_string("aeiouáéíóúü") # Among tables @a_0 [ {"a", -1, 1, nil}, {"e", -1, 2, nil}, {"o", -1, 1, nil}, {"os", -1, 1, nil}, {"á", -1, 1, nil}, {"é", -1, 2, nil}, {"í", -1, 1, nil}, {"ó", -1, 1, nil} ] @a_1 [ {"aba", -1, 2, nil}, {"ada", -1, 2, nil}, {"ida", -1, 2, nil}, {"ara", -1, 2, nil}, {"iera", -1, 2, nil}, {"ía", -1, 2, nil}, {"aría", 5, 2, nil}, {"ería", 5, 2, nil}, {"iría", 5, 2, nil}, {"ad", -1, 2, nil}, {"ed", -1, 2, nil}, {"id", -1, 2, nil}, {"ase", -1, 2, nil}, {"iese", -1, 2, nil}, {"aste", -1, 2, nil}, {"iste", -1, 2, nil}, {"an", -1, 2, nil}, {"aban", 16, 2, nil}, {"aran", 16, 2, nil}, {"ieran", 16, 2, nil}, {"ían", 16, 2, nil}, {"arían", 20, 2, nil}, {"erían", 20, 2, nil}, {"irían", 20, 2, nil}, {"en", -1, 1, nil}, {"asen", 24, 2, nil}, {"iesen", 24, 2, nil}, {"aron", -1, 2, nil}, {"ieron", -1, 2, nil}, {"arán", -1, 2, nil}, {"erán", -1, 2, nil}, {"irán", -1, 2, nil}, {"ado", -1, 2, nil}, {"ido", -1, 2, nil}, {"ando", -1, 2, nil}, {"iendo", -1, 2, nil}, {"ar", -1, 2, nil}, {"er", -1, 2, nil}, {"ir", -1, 2, nil}, {"as", -1, 2, nil}, {"abas", 39, 2, nil}, {"adas", 39, 2, nil}, {"idas", 39, 2, nil}, {"aras", 39, 2, nil}, {"ieras", 39, 2, nil}, {"ías", 39, 2, nil}, {"arías", 45, 2, nil}, {"erías", 45, 2, nil}, {"irías", 45, 2, nil}, {"es", -1, 1, nil}, {"ases", 49, 2, nil}, {"ieses", 49, 2, nil}, {"abais", -1, 2, nil}, {"arais", -1, 2, nil}, {"ierais", -1, 2, nil}, {"íais", -1, 2, nil}, {"aríais", 55, 2, nil}, {"eríais", 55, 2, nil}, {"iríais", 55, 2, nil}, {"aseis", -1, 2, nil}, {"ieseis", -1, 2, nil}, {"asteis", -1, 2, nil}, {"isteis", -1, 2, nil}, {"áis", -1, 2, nil}, {"éis", -1, 1, nil}, {"aréis", 64, 2, nil}, {"eréis", 64, 2, nil}, {"iréis", 64, 2, nil}, {"ados", -1, 2, nil}, {"idos", -1, 2, nil}, {"amos", -1, 2, nil}, {"ábamos", 70, 2, nil}, {"áramos", 70, 2, nil}, {"iéramos", 70, 2, nil}, {"íamos", 70, 2, nil}, {"aríamos", 74, 2, nil}, {"eríamos", 74, 2, nil}, {"iríamos", 74, 2, nil}, {"emos", -1, 1, nil}, {"aremos", 78, 2, nil}, {"eremos", 78, 2, nil}, {"iremos", 78, 2, nil}, {"ásemos", 78, 2, nil}, {"iésemos", 78, 2, nil}, {"imos", -1, 2, nil}, {"arás", -1, 2, nil}, {"erás", -1, 2, nil}, {"irás", -1, 2, nil}, {"ís", -1, 2, nil}, {"ará", -1, 2, nil}, {"erá", -1, 2, nil}, {"irá", -1, 2, nil}, {"aré", -1, 2, nil}, {"eré", -1, 2, nil}, {"iré", -1, 2, nil}, {"ió", -1, 2, nil} ] @a_2 [ {"ya", -1, 1, nil}, {"ye", -1, 1, nil}, {"yan", -1, 1, nil}, {"yen", -1, 1, nil}, {"yeron", -1, 1, nil}, {"yendo", -1, 1, nil}, {"yo", -1, 1, nil}, {"yas", -1, 1, nil}, {"yes", -1, 1, nil}, {"yais", -1, 1, nil}, {"yamos", -1, 1, nil}, {"yó", -1, 1, nil} ] @a_3 [ {"ic", -1, -1, nil}, {"ad", -1, -1, nil}, {"os", -1, -1, nil}, {"iv", -1, 1, nil} ] @a_4 [ {"able", -1, 1, nil}, {"ible", -1, 1, nil}, {"ante", -1, 1, nil} ] @a_5 [ {"ic", -1, 1, nil}, {"abil", -1, 1, nil}, {"iv", -1, 1, nil} ] @a_6 [ {"ica", -1, 1, nil}, {"ancia", -1, 2, nil}, {"encia", -1, 5, nil}, {"adora", -1, 2, nil}, {"osa", -1, 1, nil}, {"ista", -1, 1, nil}, {"iva", -1, 9, nil}, {"anza", -1, 1, nil}, {"logía", -1, 3, nil}, {"idad", -1, 8, nil}, {"able", -1, 1, nil}, {"ible", -1, 1, nil}, {"ante", -1, 2, nil}, {"mente", -1, 7, nil}, {"amente", 13, 6, nil}, {"acion", -1, 2, nil}, {"ucion", -1, 4, nil}, {"ación", -1, 2, nil}, {"ución", -1, 4, nil}, {"ico", -1, 1, nil}, {"ismo", -1, 1, nil}, {"oso", -1, 1, nil}, {"amiento", -1, 1, nil}, {"imiento", -1, 1, nil}, {"ivo", -1, 9, nil}, {"ador", -1, 2, nil}, {"icas", -1, 1, nil}, {"ancias", -1, 2, nil}, {"encias", -1, 5, nil}, {"adoras", -1, 2, nil}, {"osas", -1, 1, nil}, {"istas", -1, 1, nil}, {"ivas", -1, 9, nil}, {"anzas", -1, 1, nil}, {"logías", -1, 3, nil}, {"idades", -1, 8, nil}, {"ables", -1, 1, nil}, {"ibles", -1, 1, nil}, {"aciones", -1, 2, nil}, {"uciones", -1, 4, nil}, {"adores", -1, 2, nil}, {"antes", -1, 2, nil}, {"icos", -1, 1, nil}, {"ismos", -1, 1, nil}, {"osos", -1, 1, nil}, {"amientos", -1, 1, nil}, {"imientos", -1, 1, nil}, {"ivos", -1, 9, nil} ] @a_7 [ {"la", -1, -1, nil}, {"sela", 0, -1, nil}, {"le", -1, -1, nil}, {"me", -1, -1, nil}, {"se", -1, -1, nil}, {"lo", -1, -1, nil}, {"selo", 5, -1, nil}, {"las", -1, -1, nil}, {"selas", 7, -1, nil}, {"les", -1, -1, nil}, {"los", -1, -1, nil}, {"selos", 10, -1, nil}, {"nos", -1, -1, nil} ] @a_8 [ {"ando", -1, 6, nil}, {"iendo", -1, 6, nil}, {"yendo", -1, 7, nil}, {"ándo", -1, 2, nil}, {"iéndo", -1, 1, nil}, {"ar", -1, 6, nil}, {"er", -1, 6, nil}, {"ir", -1, 6, nil}, {"ár", -1, 3, nil}, {"ér", -1, 4, nil}, {"ír", -1, 5, nil} ] @a_9 [ {"", -1, 6, nil}, {"á", 0, 1, nil}, {"é", 0, 2, nil}, {"í", 0, 3, nil}, {"ó", 0, 4, nil}, {"ú", 0, 5, nil} ] @doc """ Stem a word. ### Arguments * `word` is a UTF-8 binary. ### Returns * The stemmed UTF-8 binary. """ @spec stem(binary()) :: binary() def stem(word) when is_binary(word) do state = Runtime.new(word) |> init_vars() state = run_stem(state) Runtime.assign_to(state) end defp init_vars(state), do: %{state | vars: %{p1: 0, p2: 0, pV: 0}} defp run_stem(%Runtime{} = state) do {_, state} = r_stem(state) state end # Snowball runtime helpers. defp snowball_do_f(state, fun) do saved_c = state.cursor {_, s} = fun.(state) %{s | cursor: saved_c} end defp snowball_do_b(state, fun) do rel = state.limit - state.cursor {_, s} = fun.(state) %{s | cursor: s.limit - rel} end defp snowball_test_b(state, fun) do rel = state.limit - state.cursor case fun.(state) do {:ok, s} -> {:ok, %{s | cursor: s.limit - rel}} {:fail, s} -> {:fail, %{s | cursor: s.limit - rel}} end end defp snowball_try(state, fun) do rel = state.limit - state.cursor case fun.(state) do {:ok, s} -> s {:fail, s} -> %{s | cursor: s.limit - rel} end end defp snowball_or(state, fun1, fun2) do rel = state.limit - state.cursor case fun1.(state) do {:ok, s} -> {:ok, s} {:fail, s} -> fun2.(%{s | cursor: s.limit - rel}) end end defp lift(state, :fail), do: {:fail, state} defp lift(_state, %Runtime{} = s), do: {:ok, s} defp next_codepoint(%Runtime{cursor: c, limit: lim, current: cur} = state) do case Runtime.codepoint_at(cur, c, lim) do {_cp, size} -> {:ok, %{state | cursor: c + size}} :error -> {:fail, state} end end defp r_residual_suffix(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_0) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> r_RV(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 2 -> case (fn state -> r_RV(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "u")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> snowball_test_b(state, fn state -> lift(state, Runtime.eq_s_b(state, "g")) end) end).(state) do {:ok, state} -> case (fn state -> r_RV(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end r -> r end end r -> r end end end)} end r -> r end _ -> {:ok, state} end end end).() end defp r_verb_suffix(%Runtime{} = state) do (fn -> old_limit = state.limit_backward case (fn state -> (fn -> target = state.vars[:pV] if target < state.limit_backward or target > state.limit do {:fail, state} else {:ok, %{state | cursor: target}} end end).() end).(state) do {:fail, _} -> {:fail, state} {:ok, limit_state} -> state = %{state | ket: state.cursor, limit_backward: limit_state.cursor} case Runtime.find_among_b(state, @a_1) do :fail -> {:fail, %{state | limit_backward: old_limit}} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor, limit_backward: old_limit} case result do 1 -> case (fn state -> {:ok, snowball_try(state, fn state -> case (fn state -> lift(state, Runtime.eq_s_b(state, "u")) end).(state) do {:ok, state} -> snowball_test_b(state, fn state -> lift(state, Runtime.eq_s_b(state, "g")) end) r -> r end end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} end end 2 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end end).() end defp r_y_verb_suffix(%Runtime{} = state) do (fn -> old_limit = state.limit_backward case (fn state -> (fn -> target = state.vars[:pV] if target < state.limit_backward or target > state.limit do {:fail, state} else {:ok, %{state | cursor: target}} end end).() end).(state) do {:fail, _} -> {:fail, state} {:ok, limit_state} -> state = %{state | ket: state.cursor, limit_backward: limit_state.cursor} case Runtime.find_among_b(state, @a_2) do :fail -> {:fail, %{state | limit_backward: old_limit}} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor, limit_backward: old_limit} case result do 1 -> case (fn state -> lift(state, Runtime.eq_s_b(state, "u")) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end _ -> {:ok, state} end end end end).() end defp r_standard_suffix(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_6) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 2 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "ic")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end r -> r end end end)} end r -> r end 3 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "log")} r -> r end 4 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "u")} r -> r end 5 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "ente")} r -> r end 6 -> case (fn state -> r_R1(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_3) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case (fn state -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end).(state) do {:ok, state} -> case result do 1 -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "at")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end r -> r end end _ -> {:ok, state} end r -> r end end end).() end)} end r -> r end 7 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_4) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end _ -> {:ok, state} end end end).() end)} end r -> r end 8 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_5) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end _ -> {:ok, state} end end end).() end)} end r -> r end 9 -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "at")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end r -> r end end end)} end r -> r end _ -> {:ok, state} end end end).() end defp r_attached_pronoun(%Runtime{} = state) do case (fn state -> (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_7) do :fail -> {:fail, state} {%Runtime{} = s, _result} -> state = %{s | bra: s.cursor} {:ok, state} end end).() end).(state) do {:ok, state} -> (fn -> case Runtime.find_among_b(state, @a_8) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = s case (fn state -> r_RV(state) end).(state) do {:ok, state} -> case result do 1 -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "iendo")} end 2 -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "ando")} end 3 -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "ar")} end 4 -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "er")} end 5 -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "ir")} end 6 -> {:ok, Runtime.slice_del(state)} 7 -> case (fn state -> lift(state, Runtime.eq_s_b(state, "u")) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end _ -> {:ok, state} end r -> r end end end).() r -> r end end defp r_R2(%Runtime{} = state) do if state.vars[:p2] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_R1(%Runtime{} = state) do if state.vars[:p1] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_RV(%Runtime{} = state) do if state.vars[:pV] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_mark_regions(%Runtime{} = state) do case (fn state -> {:ok, put_in(state.vars[:pV], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p1], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p2], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_f(state, fn state -> case (fn state -> snowball_or(state, fn state -> case (fn state -> lift(state, Runtime.in_grouping(state, @g_v)) end).(state) do {:ok, state} -> snowball_or(state, fn state -> case (fn state -> lift(state, Runtime.out_grouping(state, @g_v)) end).(state) do {:ok, state} -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end r -> r end end, fn state -> case (fn state -> lift(state, Runtime.in_grouping(state, @g_v)) end).(state) do {:ok, state} -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end r -> r end end) r -> r end end, fn state -> case (fn state -> lift(state, Runtime.out_grouping(state, @g_v)) end).(state) do {:ok, state} -> snowball_or(state, fn state -> case (fn state -> lift(state, Runtime.out_grouping(state, @g_v)) end).(state) do {:ok, state} -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end r -> r end end, fn state -> case (fn state -> lift(state, Runtime.in_grouping(state, @g_v)) end).(state) do {:ok, state} -> next_codepoint(state) r -> r end end) r -> r end end) end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:pV], state.cursor)} r -> r end end)} end).(state) do {:ok, state} -> {:ok, snowball_do_f(state, fn state -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p1], state.cursor)} end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:p2], state.cursor)} r -> r end r -> r end end r -> r end r -> r end end)} end end end end end defp r_postlude(%Runtime{} = state) do (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> case (fn state -> (fn -> state = %{state | bra: state.cursor} case Runtime.find_among(state, @a_9) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | ket: s.cursor} case result do 1 -> {:ok, Runtime.slice_from(state, "a")} 2 -> {:ok, Runtime.slice_from(state, "e")} 3 -> {:ok, Runtime.slice_from(state, "i")} 4 -> {:ok, Runtime.slice_from(state, "o")} 5 -> {:ok, Runtime.slice_from(state, "u")} 6 -> next_codepoint(state) _ -> {:ok, state} end end end).() end).(state) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, s} -> {:ok, %{s | cursor: state.cursor}} end end) end defp r_stem(%Runtime{} = state) do case (fn state -> {:ok, snowball_do_f(state, fn state -> r_mark_regions(state) end)} end).(state) do {:ok, state} -> case (fn state -> (fn state -> old_cursor = state.cursor old_lb = state.limit_backward state = %{state | cursor: state.limit, limit_backward: old_cursor} {tag, s} = (fn state -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_attached_pronoun(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> snowball_or(state, fn state -> snowball_or(state, fn state -> r_standard_suffix(state) end, fn state -> r_y_verb_suffix(state) end) end, fn state -> r_verb_suffix(state) end) end)} end).(state) do {:ok, state} -> {:ok, snowball_do_b(state, fn state -> r_residual_suffix(state) end)} end end end).(state) {tag, %{s | cursor: old_cursor, limit_backward: old_lb}} end).(state) end).(state) do {:ok, state} -> {:ok, snowball_do_f(state, fn state -> r_postlude(state) end)} end end end end