     iex> WordFinder.similarity "cozy", "fullers"
     0
   """
+  @spec similar_to(Enumerable.t, String.t, integer) :: Enumerable.t
   def similar_to(words, compare_word, min_similarity) do
     Stream.filter(words, fn word ->
       similarity(word, compare_word) >= min_similarity
     end)
   end
 
+  @spec similarity(String.t, String.t) :: integer
   def similarity(a, b) do
     a
     |> compare_words(b)

      iex> WordFinder.compare "pineapple", "apple"
      {["p", "i", "n", "e"], []}
  """
  def compare_words(a, b)
  when is_bitstring(a) and is_bitstring(b) do
    a = a |> String.codepoints
    b = b |> String.codepoints
    compare_words(a, b)

  the amount they should appear in the word. For example,
  `%{a: 4, k: 2}` will return all words with exactly 4 a's and 2 k's.
  """
  @spec containing(Enumerable.t, map, list) :: Enumerable.t
  def containing(words, constraints, opts \\ []) do
    opts = Keyword.put_new(opts, :precise, true)
    words |> Stream.filter(&contains?(&1, constraints, opts))
