Packages

The SpellChecker module checks word correctness and suggests alternatives.

Current section

Files

Jump to
spell_checker lib spell_checker.ex
Raw

lib/spell_checker.ex

defmodule SpellChecker do
require Logger
@moduledoc """
The `SpellChecker` module is designed to check the correctness of words against a predefined word list and provide suggestions for incorrect words.
## Functions
`is_correct?/2`
`is_correct/1`
`is_correct!/2`
"""
@file_path "lib\\wordlist.txt"
def is_correct?(word_list, acc \\ [])
def is_correct?([], acc) do
acc
end
@doc """
`is_correct?/2`
This function checks if a list of words are correct and returns a list of the correct words.
Parameters:
`word_list` (list): A list of words to check.
`acc` (list, optional): An accumulator for correct words (used internally, defaults to an empty list).
Returns: A list of correct words.
## Examples
iex> words = ["hello", "worlld", "Programming"]
iex> correct_words = SpellChecker.is_correct?(words)
iex> ["hello", "Elixir"]
"""
def is_correct?([new_word | rest], acc) do
case MapSet.member?(load_word_list(), String.downcase(new_word)) do
true ->
is_correct?(rest, [new_word | acc])
_ ->
is_correct?(rest, acc)
end
end
@doc """
`is_correct/1`
This function checks if a single word is correct.
Parameters:
word (string): A word to check.
Returns: A tuple indicating if the word is correct.
## Examples
iex> SpellChecker.is_correct("hello")
iex> {:ok, true}
iex> SpellChecker.is_correct("worlld")
iex> {:none, false}
"""
def is_correct(word) when is_bitstring(word) and word != "" do
case MapSet.member?(load_word_list(), word) do
true ->
{:ok, true}
false ->
{:none, false}
end
end
@doc """
`is_correct!/2`
This function checks if a single word is correct and provides suggestions if it is not.
Parameters:
`word` (string): A word to check.
`suggest` (integer, optional): The number of suggestions to return (defaults to 5).
## Examples
iex> SpellChecker.is_correct!("hello")
iex> {:ok, true}
iex> SpellChecker.is_correct!("worlld", 3)
iex> ["world", "word", "would"]
"""
def is_correct!(word, suggest \\ 5) when is_bitstring(word) and word != "" do
case MapSet.member?(load_word_list(), word) do
true ->
{:ok, true}
false ->
suggest(word, suggest)
end
end
defp suggest(word, suggest) do
Enum.reduce(load_word_list() |> Enum.to_list(), [], fn e, acc ->
if Simetric.Jaro.Winkler.compare(e, word) > 0.85 do
[e | acc]
else
acc
|> Enum.slice(0..suggest)
end
end)
end
defp load_word_list() do
File.stream!(@file_path)
|> Stream.map(&String.trim/1)
|> Enum.into(MapSet.new())
end
end