Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Last active July 10, 2023 07:06
Show Gist options
  • Save ityonemo/05e861d7a4cb3f94dbd19ea829f61f52 to your computer and use it in GitHub Desktop.
Save ityonemo/05e861d7a4cb3f94dbd19ea829f61f52 to your computer and use it in GitHub Desktop.
matching module.exs
defmodule Aaa do
# terminal condition. If we've gotten through the whole pattern we're done.
def matches(<<>>, <<>>), do: true
# If the first character matches and has a question mark we must make an
# epsilon transition. We have to try both "universes". In one "universe"
# we proceed as if we consumed the optional match, and the other we proceed
# as if we didn't. The success of either means the match succeeds. This
# means for this branch we don't get TCO =( but this should be relatively rare.
def matches(<<char, ??, rest1 :: binary>>, string = <<char, rest2 :: binary>>) do
matches(rest1, rest2) or matches(rest1, string)
end
# the case where the match character is optional and both matche is handled
# above, so in this case know the first character must mismatch, and we proceed
# to the next iteration, ignoring the optional from the match and using the whole
# rest of the string.
def matches(<<_, ??, rest1 :: binary>>, string) do
matches(rest1, string)
end
# the case where the match is nonoptional and both match we proceed to the next
# iteration, dropping both first characters
def matches(<<char, rest1 :: binary>>, <<char, rest2 :: binary>>) do
matches(rest1, rest2)
end
# none of the other cases apply so we know it's a mismatch
def matches(_, _), do: false
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment