Just rewrote my matcher app in Erlang for evaluating expressions against maps with a funny query language build out of Erlang tuples.
Evaluates expressions like
matcher:eval({'=', <<"Albert">>, <<"Albert">>})
Expressions are tuples in one of the following form:
{ Op, Arg }
{ Op, Arg1, Arg2 }
{ Op, [Arg, ...] }
Expressions can be nested: Any argument can be an expression again:
{'&', [{'=', <<"Albert">>, <<"Albert">>}, {'=', <<"Berta">>, <<"Albert">>}]}
matcher:eval/2 allows to specify a Provider, which is a fun/1 evaluates expression that can not be evaluated any further.
Example: If you have a map with atoms as keys, these keys can be replaces by its corresponding value.
Map = #{ name => <<"Albert">> }.
true = matcher:eval(Map, {'=', name, <<"Albert">>}). 
matcher:eval(Map, Expr) is short for matcher:eval(map_provider(Map), Expr).
You can use any fun/1 as a provider.
BTW: If you like you can specify new operators with such a function, just handle something like {my_cool_op, A, B} in your function.
List of Operators:
- One operand
    - !,- not
 
- Many operands (list)
    - &,- and
- |,- or
 
- Two operands
    - <,- lt: less then
- <~,- {lt, case_insensitive}: less then (case insensitive)
- >,- gt: greater then
- >~,- {gt, case_insensitive}: greater then (case insensitive)
- >=,- =>,- le: less then or equal
- >=~,- =>~,- {lt, case_insensitive}: less then or equal (case insensitive)
- <=,- =<,- le: less then or equal
- <=~,- =<~,- {lt, case_insensitive}: less then or equal (case insensitive)
- =,- ==,- eq: equal
- =~,- {eq, case_insensitive}: equal (case insensitive)
- ?,- part_of: first string is part of second
- ?~,- {part_of, case_insensitive}: first string is part of second (case insensitive)
 
See ./test/matcher_SUITE.erl
License
License is MIT … but I like to hear from you, if you think this app is useful. :-)