У меня вполне конкретный вопрос по Хаскелю, на который не могу пока найти ответа.
См. код:
f :: a->a
-- имплементация не важна
toString:: a->String
toString (f x) = "Applied f"
toString _ = "any"
То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете.
Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе.
Как мне это сделать?
Здравствуйте, barn_czn, Вы писали:
_>У меня вполне конкретный вопрос по Хаскелю, на который не могу пока найти ответа. _>См. код:
_>f :: a->a _>-- имплементация не важна
_>toString:: a->String _>toString (f x) = "Applied f" _>toString _ = "any"
_>То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете. _>Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе. _>Как мне это сделать?
Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, barn_czn, Вы писали:
_>>У меня вполне конкретный вопрос по Хаскелю, на который не могу пока найти ответа. _>>См. код:
_>>f :: a->a _>>-- имплементация не важна
_>>toString:: a->String _>>toString (f x) = "Applied f" _>>toString _ = "any"
_>>То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете. _>>Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе. _>>Как мне это сделать?
G>Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
А разве я его не создаю строя цепочку вызовов? Где же все то что обещали в Хаскеле — ленивость вычислений, все есть функция.
Вот я и хочу воспользоватся ленивостью Хаскеля и покапатся в другой функции.
Я согласен изменить сигнатуру на
toString:: (a->a)->String
Но я точно не хочу внутри ФЯ строить еще одну объектную модель выражений и деревьев.
Здравствуйте, barn_czn, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, barn_czn, Вы писали:
_>>>У меня вполне конкретный вопрос по Хаскелю, на который не могу пока найти ответа. _>>>См. код:
_>>>f :: a->a _>>>-- имплементация не важна
_>>>toString:: a->String _>>>toString (f x) = "Applied f" _>>>toString _ = "any"
_>>>То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете. _>>>Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе. _>>>Как мне это сделать?
G>>Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
_>А разве я его не создаю строя цепочку вызовов? Где же все то что обещали в Хаскеле — ленивость вычислений, все есть функция.
Создавать то создаешь, но это деталь реализации. В системе типов никак не отражается, соответственно и матчинг сделать не можешь.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, barn_czn, Вы писали:
_>>Здравствуйте, gandjustas, Вы писали:
G>>>Здравствуйте, barn_czn, Вы писали:
_>>>>У меня вполне конкретный вопрос по Хаскелю, на который не могу пока найти ответа. _>>>>См. код:
_>>>>f :: a->a _>>>>-- имплементация не важна
_>>>>toString:: a->String _>>>>toString (f x) = "Applied f" _>>>>toString _ = "any"
_>>>>То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете. _>>>>Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе. _>>>>Как мне это сделать?
G>>>Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
_>>А разве я его не создаю строя цепочку вызовов? Где же все то что обещали в Хаскеле — ленивость вычислений, все есть функция. G>Создавать то создаешь, но это деталь реализации. В системе типов никак не отражается, соответственно и матчинг сделать не можешь.
Понятно. Ну а функцию я не могу разобрать? Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
Здравствуйте, barn_czn, Вы писали:
_>Здравствуйте, gandjustas, Вы писали:
G>>>>Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
_>>>А разве я его не создаю строя цепочку вызовов? Где же все то что обещали в Хаскеле — ленивость вычислений, все есть функция. G>>Создавать то создаешь, но это деталь реализации. В системе типов никак не отражается, соответственно и матчинг сделать не можешь.
_>Понятно. Ну а функцию я не могу разобрать? Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
Для compile-time копания есть Template Haskell, но хаскель, наверное, не лучший язык для таких манипуляций (по сравнению с немерлами/лиспами), и обычно задачу стараются переформулировать чтобы свести её на уровень типов/данных.
Здравствуйте, barn_czn, Вы писали:
_>Понятно. Ну а функцию я не могу разобрать?
Нет
_>Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
Expression это не функция. Компилятор C# генерирует разный код для функции и для Expresson.
Если хочешь так играиться, то кури F# и ReflectedDefinitionAttribute.
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, barn_czn, Вы писали:
_>>Здравствуйте, gandjustas, Вы писали:
G>>>>>Для того чтобы копаться в дереве выражения надо его создать. Вызов функции != дерево выражения.
_>>>>А разве я его не создаю строя цепочку вызовов? Где же все то что обещали в Хаскеле — ленивость вычислений, все есть функция. G>>>Создавать то создаешь, но это деталь реализации. В системе типов никак не отражается, соответственно и матчинг сделать не можешь.
_>>Понятно. Ну а функцию я не могу разобрать? Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
К>Для compile-time копания есть Template Haskell, но хаскель, наверное, не лучший язык для таких манипуляций (по сравнению с немерлами/лиспами),
Пока не соглашусь. Смотрел и лиспы и ф-шарпы, и немерлы. Хаскель , для меня, пока лучшее что есть в ФП.
Аргументы — он более чист от императивщины , мощный полиморфизм и обобщенное программирование.
Немерл и ф-шарп — я пока не понимаю зачем. После того как появился LINQ на шарпах — смешаные языки, на дотнете, потеряли свою ценность, имхо.
Здравствуйте, barn_czn, Вы писали:
_>Здравствуйте, Курилка, Вы писали:
К>>Здравствуйте, barn_czn, Вы писали:
_>>>Понятно. Ну а функцию я не могу разобрать? Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
К>>Для compile-time копания есть Template Haskell, но хаскель, наверное, не лучший язык для таких манипуляций (по сравнению с немерлами/лиспами),
_>Пока не соглашусь. Смотрел и лиспы и ф-шарпы, и немерлы. Хаскель , для меня, пока лучшее что есть в ФП. _>Аргументы — он более чист от императивщины , мощный полиморфизм и обобщенное программирование. _>Немерл и ф-шарп — я пока не понимаю зачем. После того как появился LINQ на шарпах — смешаные языки, на дотнете, потеряли свою ценность, имхо.
Тут вопрос не про то, что ты манипуляции хочешь делать, а про то, что манипуляции над AST самого языка ты хочешь делать в compile-time, если же ты просто будешь манипулировать AST, то это совсем другая ситуация.
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, barn_czn, Вы писали:
_>>Здравствуйте, Курилка, Вы писали:
К>>>Здравствуйте, barn_czn, Вы писали:
_>>>>Понятно. Ну а функцию я не могу разобрать? Я имею ввиду чтото вроде рефлекшена, или Expression<> на шарпах. Expression<> — тоже функция, но я могу посмотреть ее дерево. На Хаскеле нет такого?
К>>>Для compile-time копания есть Template Haskell, но хаскель, наверное, не лучший язык для таких манипуляций (по сравнению с немерлами/лиспами),
_>>Пока не соглашусь. Смотрел и лиспы и ф-шарпы, и немерлы. Хаскель , для меня, пока лучшее что есть в ФП. _>>Аргументы — он более чист от императивщины , мощный полиморфизм и обобщенное программирование. _>>Немерл и ф-шарп — я пока не понимаю зачем. После того как появился LINQ на шарпах — смешаные языки, на дотнете, потеряли свою ценность, имхо.
К>Тут вопрос не про то, что ты манипуляции хочешь делать, а про то, что манипуляции над AST самого языка ты хочешь делать в compile-time, если же ты просто будешь манипулировать AST, то это совсем другая ситуация.
Не, я же пишу код для периода исполнения, а не компиляции. Поэтому я ожидаю средства доступа к АСТ именно в период исполнения.
Почему я наивно этого ожидаю? По аналогии с Expression на шарпах. Там, написав лямбду, я могу ее разобрать именно в runtime периоде.
Вообще удивляет, например, почему нет '==' для функций.
Здравствуйте, barn_czn, Вы писали:
_>Здравствуйте, Курилка, Вы писали:
К>>Тут вопрос не про то, что ты манипуляции хочешь делать, а про то, что манипуляции над AST самого языка ты хочешь делать в compile-time, если же ты просто будешь манипулировать AST, то это совсем другая ситуация.
_>Не, я же пишу код для периода исполнения, а не компиляции. Поэтому я ожидаю средства доступа к АСТ именно в период исполнения. _>Почему я наивно этого ожидаю? По аналогии с Expression на шарпах. Там, написав лямбду, я могу ее разобрать именно в runtime периоде. _>Вообще удивляет, например, почему нет '==' для функций.
Рассуждения по аналогии периодически спотыкаются на границах аналогий
Про Eq для функций это чуть ли не типичный вопрос, варианты ответа: раз, два, наверняка есть ещё пачка их.
По сути чистота, про которую ты выше писал, тут и сказывается — за всё приходится платить
Здравствуйте, barn_czn, Вы писали:
_>То что toString не компилится я уже понял почему, патерн матчинг не такой мощный как я ожидал, и этому есть объяснение. Но цель функции toString я думаю вы поймете. _>Я хочу, используя патерн-матчинг, покапаться в дереве выражения на входе. _>Как мне это сделать?
Для этого подойдут языки, основанные на term rewriting, где нет принипиального различия между применением функции и применением конструктора, например, Pure или Wolfram Language.
Здравствуйте, barn_czn, Вы писали:
_>Вообще удивляет, например, почему нет '==' для функций.
А какое поведение ты бы ожидал от этого оператора? Функции равны тогда и только тогда, когда их результаты равны (с точки зрения оператора ==) для любого аргумента? Или что-то другое?
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, barn_czn, Вы писали:
_>>Вообще удивляет, например, почему нет '==' для функций.
N>А какое поведение ты бы ожидал от этого оператора? Функции равны тогда и только тогда, когда их результаты равны (с точки зрения оператора ==) для любого аргумента? Или что-то другое?
Такое же как в других языках где есть элементы ФП. C# — равенство делегатов запросто проверяется.
Здравствуйте, barn_czn, Вы писали:
_>>>Вообще удивляет, например, почему нет '==' для функций.
N>>А какое поведение ты бы ожидал от этого оператора? Функции равны тогда и только тогда, когда их результаты равны (с точки зрения оператора ==) для любого аргумента? Или что-то другое?
_>Такое же как в других языках где есть элементы ФП. C# — равенство делегатов запросто проверяется.
Вот что говорит спецификация C# по поводу равенства делегатов (обрати внимание, что результат не является детерминистическим, и транзитивность не гарантируется):
Two delegate instances are considered equal as follows:
• If either of the delegate instances is null, they are equal if and only if both are null.
• If the delegates have different run-time type they are never equal.
• If both of the delegate instances have an invocation list, those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list.
The following rules govern the equality of invocation list entries:
• If two invocation list entries both refer to the same static method then the entries are equal.
• If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
• Invocation list entries produced from evaluation of semantically identical anonymous-function-expressions with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, barn_czn, Вы писали:
_>>>>Вообще удивляет, например, почему нет '==' для функций.
N>>>А какое поведение ты бы ожидал от этого оператора? Функции равны тогда и только тогда, когда их результаты равны (с точки зрения оператора ==) для любого аргумента? Или что-то другое?
_>>Такое же как в других языках где есть элементы ФП. C# — равенство делегатов запросто проверяется.
N>Вот что говорит спецификация C# по поводу равенства делегатов (обрати внимание, что результат не является детерминистическим, и транзитивность не гарантируется):
N>
N>Two delegate instances are considered equal as follows:
N>• If either of the delegate instances is null, they are equal if and only if both are null.
N>• If the delegates have different run-time type they are never equal.
N>• If both of the delegate instances have an invocation list, those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list.
N>The following rules govern the equality of invocation list entries:
N>• If two invocation list entries both refer to the same static method then the entries are equal.
N>• If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
N>• Invocation list entries produced from evaluation of semantically identical anonymous-function-expressions with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.
N>Предложи свою переформулировку для Haskell.
Я не хочу предлагать формулировки. Я хочу хоть как то сравнить две функции. Почему вдруг решили, что сравнение функций — это обязательно доказательство того что функции идентичны.
Что, нельзя просто сравнить равны ли ссылки на эти две функции?
Да, пусть это будет не Eq. Пусть это будет отдельная функция funRefEq. Меня бы устроило. И разработчикам ХАскеля это ничего не стоило бы. Но ее нет я так понимаю.
Здравствуйте, barn_czn, Вы писали:
_>Да, пусть это будет не Eq. Пусть это будет отдельная функция funRefEq. Меня бы устроило. И разработчикам ХАскеля это ничего не стоило бы. Но ее нет я так понимаю.
что-то такое низкоуровнево-ссылочное там есть, я просто забыл назвавние за давностью лет.
а в общем виде — это сравнение двух лямбд, что сам понимаешь нереально