perf: Removed pop_grapheme and used pattern matching first letter
Some checks failed
test / test (push) Has been cancelled

This commit is contained in:
2025-11-04 13:57:29 +00:00
parent 7793bbb3a3
commit 5feb4de7a4

View File

@@ -1,7 +1,6 @@
import gleam/bool import gleam/bool
import gleam/dict import gleam/dict
import gleam/int import gleam/int
import gleam/io
import gleam/list import gleam/list
import gleam/option.{None, Some} import gleam/option.{None, Some}
import gleam/result import gleam/result
@@ -266,45 +265,75 @@ pub fn stem(word: String, rules: Rules) -> String {
} }
fn do_stem(word: String, rules: Rules, intact: Bool) -> String { fn do_stem(word: String, rules: Rules, intact: Bool) -> String {
case string.reverse(word) |> string.pop_grapheme { case string.reverse(word) {
Ok(#(letter, _)) -> { "a" as letter <> _
case dict.get(rules, letter) { | "b" as letter <> _
Ok(specific_rules) -> { | "c" as letter <> _
let #(stem, restem, intact) = | "d" as letter <> _
list.fold_until( | "e" as letter <> _
specific_rules, | "f" as letter <> _
#(word, False, intact), | "g" as letter <> _
fn(state, rule) { | "h" as letter <> _
case rule_matches(rule, word, intact) { | "i" as letter <> _
True -> { | "j" as letter <> _
let result = apply_rule(rule, word) | "k" as letter <> _
case is_valid(result) { | "l" as letter <> _
False -> list.Continue(state) | "m" as letter <> _
True -> { | "n" as letter <> _
list.Stop(#(result, rule.restem, False)) | "o" as letter <> _
} | "p" as letter <> _
} | "q" as letter <> _
} | "r" as letter <> _
False -> list.Continue(state) | "s" as letter <> _
} | "t" as letter <> _
}, | "u" as letter <> _
) | "v" as letter <> _
case restem { | "w" as letter <> _
True -> do_stem(stem, rules, intact) | "x" as letter <> _
False -> stem | "y" as letter <> _
} | "z" as letter <> _ -> {
} case stem_letter(rules, letter, word, intact) {
Error(_) -> word #(stem, True, intact) -> do_stem(stem, rules, intact)
#(stem, _, _) -> stem
} }
} }
Error(_) -> word
_ -> word
}
}
fn stem_letter(
rules: dict.Dict(String, List(Rule)),
letter: String,
word: String,
intact: Bool,
) -> #(String, Bool, Bool) {
case dict.get(rules, letter) {
Ok(specific_rules) -> {
// let #(stem, restem, intact) =
list.fold_until(specific_rules, #(word, False, intact), fn(state, rule) {
case rule_matches(rule, word, intact) {
True -> {
let result = apply_rule(rule, word)
case is_valid(result) {
False -> list.Continue(state)
True -> {
list.Stop(#(result, rule.restem, False))
}
}
}
False -> list.Continue(state)
}
})
}
Error(_) -> #(word, False, False)
} }
} }
fn rule_matches(rule: Rule, word: String, stem_intact: Bool) -> Bool { fn rule_matches(rule: Rule, word: String, stem_intact: Bool) -> Bool {
case !stem_intact && rule.intact { case stem_intact || !rule.intact {
True -> False True -> string.ends_with(word, rule.suffix)
False -> string.ends_with(word, rule.suffix) False -> False
} }
} }