Комментарии 14
Весьма и весьма красиво! Я сам любитель навертеть чего-нибудь удобного и необычного на синтаксических фишках языка.
Одно предложение: добавьте, пожалуйста, экстеншн метод аля ToFunc, чтобы можно было объявлять матчеры через var, а то много пользователей, среди которых я, пишут сначала new Matcher...., а потом жмут introduce variable в решарпере. В этом случае можно написать .ToFunc и тип станет функцией:
Одно предложение: добавьте, пожалуйста, экстеншн метод аля ToFunc, чтобы можно было объявлять матчеры через var, а то много пользователей, среди которых я, пишут сначала new Matcher...., а потом жмут introduce variable в решарпере. В этом случае можно написать .ToFunc и тип станет функцией:
public static class MatcherEx
{
public static Func<T1, T2> ToFunc<T1, T2>(this Matcher<T1, T2> matcher)
{
return matcher;
}
}
...
var matcher = new Matcher<string, int>
{
{s => true, s => s.Length}
}.ToFunc();
var i = matcher("asd");
+2
При всем моем уважении, это не pattern matching ни разу. Все что угодно, но не _сопоставление с образцом_.
+1
Вас смущает отсутствие готовых дискриминаторов для коллекций?
0
Нет конечно :-)
В первую очередь, меня «смущает» отсутствие _образца_ как такового. Предикат не является образцом, и не может таковым быть. По той простой причине, что предикат не способен определить контекст, связывающий… кхм… скажем так… «правую» и «левую» части «выражения» сопоставления.
В первую очередь, меня «смущает» отсутствие _образца_ как такового. Предикат не является образцом, и не может таковым быть. По той простой причине, что предикат не способен определить контекст, связывающий… кхм… скажем так… «правую» и «левую» части «выражения» сопоставления.
0
Вы правы, но единственный способ так сделать, который мне удалось придумать — объединять предикат и функцию в объект «дискриминатор», что выглядит уже не так красиво
У меня была изначально идея сделать что-то вроде
Но C# не позволяет писать такие выражения.
У меня была изначально идея сделать что-то вроде
s => string.IsNullOrEmpty(s) => 0
Но C# не позволяет писать такие выражения.
0
Да дело-то не в этом.
Каким именно образом будет задаваться _образец_ дело конечно важное, но не настолько.
Проблема как раз в том, что результат сопоставления — это — грубо говоря — не true/false. Результат сопоставления — это контекст. Сам процесс сопоставления — это, по большому счету, процесс построения контекста. Удалось построить — сопоставление удалось. Не удалось — результатом будет контекст, определяющий исключительную ситуацию в том или ином виде.
Если «на пальцах» — то в вашем случае, вычисление правого выражения пары, должно происходить в контексте, полученном в результате вычисления левого выражения пары. Т.е. левое выражение должно быть не предикатом, а функцией возвращающей, например, Expression.
Каким именно образом будет задаваться _образец_ дело конечно важное, но не настолько.
Проблема как раз в том, что результат сопоставления — это — грубо говоря — не true/false. Результат сопоставления — это контекст. Сам процесс сопоставления — это, по большому счету, процесс построения контекста. Удалось построить — сопоставление удалось. Не удалось — результатом будет контекст, определяющий исключительную ситуацию в том или ином виде.
Если «на пальцах» — то в вашем случае, вычисление правого выражения пары, должно происходить в контексте, полученном в результате вычисления левого выражения пары. Т.е. левое выражение должно быть не предикатом, а функцией возвращающей, например, Expression.
+4
Вроде в C# есть замыкания. Объединение легко делается как замыкание, получающее параметрами две функции, и вызывающая одну из них с параметром нужного типа.
0
Добрый день, скажите а почему вам не подошли похожие решения вроде May(http://twistedoakstudios.com/blog/Post1130_when-null-is-not-enough-an-option-type-for-c) или Scalesque(http://noelkennedy.github.io/scalesque/)?
0
Здравствуйте. Scalesque не использует деревьев выражений, что порождает оверхед на вызовы функций при сопоставлении. May я не находил ранее, но судя по коду он работает схожим со Scalesque образом
0
Понятно, т.е. вы бы не рекомендовали ваше решение тем для кого быстродействие критично? Вопрос без подвоха.
0
0
Моё решение по сути генерирует код, эквивалентный цепочным if'ам. Единственное, что стоит учитывать — время компиляции Expression, но она происходит лишь однажды — при первом сопоставлении либо при приведении к Func.
По крайней мере, при использовании ExprMatcher в продакшене деградации производительности по сравнению с цепочным if'ом замечено не было
По крайней мере, при использовании ExprMatcher в продакшене деградации производительности по сравнению с цепочным if'ом замечено не было
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Публикации
Изменить настройки темы
Ещё один Pattern Matching на C#