Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.
def a=SomeHavyFunction1();
def b=SomeHavyFunction2();
match(a, b)
{
|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
|(_, 5) => 3
|(6, 6) => 4
}
Здравствуйте, Ka3a4oK, Вы писали:
KK>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.
KK>
KK>def a=SomeHavyFunction1();
KK>def b=SomeHavyFunction2();
KK>match(a, b)
KK>{
KK>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, 5) => 3
KK>|(6, 6) => 4
KK>}
KK>
Можно вот так:
using Nemerle;
....
def a = SomeFuncA(6);
def b = lazy(SomeFuncB(6)); // макрос lazy - изготавливает экземпляр LazyValue
match(a, b)
{
|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
|(_, LazyValue where ( Value = 5 )) => 3
|(6, LazyValue where ( Value = 6 )) => 4
| _ => 0;
}
def a=SomeHavyFunction1();
def b=SomeHavyFunction2();
match(a, b)
{
|(option.Some(v), _) => v //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
|(_, option.Some(v)) => v
|(option.None(), option.None()) => ...
}
Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?
Здравствуйте, Ka3a4oK, Вы писали:
KK>А если более сложный пример:
KK>
KK>def a=SomeHavyFunction1();
KK>def b=SomeHavyFunction2();
KK>match(a, b)
KK>{
KK>|(option.Some(v), _) => v //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, option.Some(v)) => v
KK>|(option.None(), option.None()) => ...
KK>}
KK>
Во-первых option можно не указывать, варианта Nemerle.Core.option находится в using-ах по-умолчанию.
Во-вторых все точно также:
match(a, b)
{
|(Some(v), _) => v
|(_, LazyValue where ( Value = Some(v) )) => v
|(None(), LazyValue where ( Value = None() )) => 0
}
Здравствуйте, Ka3a4oK, Вы писали:
KK>Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?
Никому это было не нужно.
Но если операция частая, то можно генерировать шаблон LazyValue автоматом, для этого нужно написать макрос lazy match, использование которого может выглядеть так:
lazy match(...)
{
| lazy(x) =>
}
Макрос ищет шаблоны lazy(x) и преобразовывает их к виду: LazyValue where ( Value = x ).
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?
H>Никому это было не нужно. H>Но если операция частая, то можно генерировать шаблон LazyValue автоматом, для этого нужно написать макрос lazy match, использование которого может выглядеть так: H>
H>lazy match(...)
H>{
H> | lazy(x) =>
H>}
H>
H>Макрос ищет шаблоны lazy(x) и преобразовывает их к виду: LazyValue where ( Value = x ).
Осталось дождаться знатоков ActiveMatch, возможно такую штуку возможно реализовать в рамках этого крутого макроса (я с ним покачто не разбирался).
Здравствуйте, hardcase, Вы писали:
H>Осталось дождаться знатоков ActiveMatch, возможно такую штуку возможно реализовать в рамках этого крутого макроса (я с ним покачто не разбирался).
ActiveMatch это поддерживает изначально
Здравствуйте, Ka3a4oK, Вы писали:
KK>Можно подробнее про актив матч?
Он был добавлен в F# для разбора объектов, которые не являются размеченными объединениями, но помимо этого его можно использовать для декомпозиции pattern matching в случае, когда правило в левой части является слишком длинным. Для последней цели я добавил его реализацию в Nemerle, так как для разбора не вариантов в Nemerle уже есть конструкция, её hardcase уже выше приводил ( | LazyValue where ( Value = 5 ))).
Здравствуйте, Рысцов Денис, Вы писали:
РД>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Можно подробнее про актив матч?
РД>Он был добавлен в F# для разбора объектов, которые не являются размеченными объединениями, но помимо этого его можно использовать для декомпозиции pattern matching в случае, когда правило в левой части является слишком длинным. Для последней цели я добавил его реализацию в Nemerle, так как для разбора не вариантов в Nemerle уже есть конструкция, её hardcase уже выше приводил ( | LazyValue where ( Value = 5 ))).
На самом деле у нас просто нет такого специфического вида макросов, которые можно раскрывать раскрываться в шаблонах match-а.
Здравствуйте, Ka3a4oK, Вы писали:
KK>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.
KK>
KK>def a=;
KK>def b=SomeHavyFunction2();
KK>match(a, b)
KK>{
KK>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, 5) => 3
KK>|(6, 6) => 4
KK>}
KK>
Начнем с того, что этот код не корректен. match не полный.
Перепиши код:
if (a == 5)
...
else match (a, SomeHavyFunction2())
{
| (_, 5) => 3
| (6, 6) => 4
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ленивые вычисления
От:
Аноним
Дата:
12.12.10 18:57
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Ka3a4oK, Вы писали:
KK>>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.
KK>>
KK>>def a=;
KK>>def b=SomeHavyFunction2();
KK>>match(a, b)
KK>>{
KK>>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>>|(_, 5) => 3
KK>>|(6, 6) => 4
KK>>}
KK>>
VD>Начнем с того, что этот код не корректен. match не полный.
VD>Перепиши код: VD>
Здравствуйте, Аноним, Вы писали:
А>не красиво.... если отложенные применяются, то синтаксис должен быть минимален
То есть лучше неправильно и непонятно, но красиво и минимально? Мне такой баланс не нравится.
Re[4]: Ленивые вычисления
От:
Аноним
Дата:
12.12.10 19:40
Оценка:
Здравствуйте, catbert, Вы писали:
C>Здравствуйте, Аноним, Вы писали:
А>>не красиво.... если отложенные применяются, то синтаксис должен быть минимален
C>То есть лучше неправильно и непонятно, но красиво и минимально? Мне такой баланс не нравится.
много кода зачастую может понять и запомнить только автор. В чем тут неправильность я не понял.
сейчас код позволяет сделать ошибки.
lazyvalue where (value=5) много не интуитивного кода
5 проще и понятнее
Здравствуйте, Ziaw, Вы писали:
Z>Почему матчащийся объект передается последним аргументом? Это не очень логично, на мой взгляд.
Немного логики здесь есть, это связано с тем, что тип активного case без параметров это 'a->optional['b], где 'a — тип разбираемого объекта. Представим теперь "фабрику" активных case'ов с одним параметром, её тип: 'c->('a->optional['b]) в haskell это и тип функции, которая возвращает функцию, и тип функции двух переменных, а в Nemerle тип функции от двух переменных: ('c*'a)->optional['b]. Именно эту сигнатуру и имеет параметрический активный case