perf: Removed pop_grapheme and used pattern matching first letter
Some checks failed
test / test (push) Has been cancelled
Some checks failed
test / test (push) Has been cancelled
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user