Похоже, что обсуждение в комментариях как бы сошло с рельсов. Во всяком случае, у меня есть другой взгляд на это, поэтому позвольте мне предложить ответ.
Я бы сказал, что Haskell уже имеет функцию, аналогичную обратному цитированию, и вы, вероятно, широко использовали ее в своем программировании на Haskell, даже не осознавая этого.
Вы провели параллель между списками Lisp и списками Haskell, но в Lisp S-выражение (т. Е. "Пары с атомами", особенно с атомарными символами) - это гибкая и вездесущая структура данных, используемая не только для представления Лисп-код, но также и как переходное представление, это как минимум первое соображение для любых сложных структурированных данных. Таким образом, большинство программ на Лиспе тратят много времени на генерацию и управление этими структурами, поэтому «литералы» S-выражений часто встречаются в коде на Лиспе. И S-выражение «почти литералы», где необходимо вычислить несколько подвыражений, более удобно писать с использованием механизма обратных кавычек, чем пытаться создать выражение с меньшими литералами и вычисляемыми фрагментами, используя такие функции, как cons
, list
, append
и т. Д.
Сравните, что с Haskell - списки на Haskell, безусловно, популярны в коде на Haskell и представляют собой структуру перехода для представления однородных последовательностей, но они обеспечивают лишь небольшую долю гибкости S-выражений. Вместо этого соответствующая вездесущая структура данных в Haskell - это алгебраический тип данных (ADT).
Ну, так же, как Lisp с его S-выражениями, программы на Haskell тратят много времени на генерацию и манипулирование ADT, а Haskell также имеет удобный синтаксис для литералов ADT и «почти литералов». Они объединены в единый синтаксис «приложения функции» с литеральными и вычисляемыми частями, дифференцированными с помощью использования конструкторов (идентификаторы с начальной заглавной буквой или инфиксные операторы, начинающиеся с двоеточия) по сравнению с неконструкторами (идентификаторы с начальной строчной буквой или инфиксом). операторы без начального двоеточия). Конечно, для некоторых конструкторов (списков и кортежей) существует некоторый дополнительный синтаксис.
Например, сравните следующие выражения в кавычках в Lisp и Haskell:
;; Lisp
(setq baz `(node ,id
(node ,(+ id 1) ,left-tree leaf)
(node ,(+ id 2) leaf ,right-tree)))
-- Haskell
baz = Node id (Node (id + 1) left_tree Leaf) (Node (id + 2) Leaf right_tree)
В Haskell-версии этого «почти литерала» конструкторы Node
и Leaf
представляют цитируемые части; инфиксные выражения left-tree
, right-tree
и +
представляют вычисленные части, и они синтаксически различимы по обычным правилам для конструкторов и неконструкторов.
Конечно, совершенно отдельно от этого есть механизм Template Haskell, который напрямую манипулирует фрагментами кода на Haskell во время компиляции. Хотя код представлен в виде ADT, который в принципе может быть написан с использованием того же «почти буквального» синтаксиса, который используется для других ADT, рассматриваемый ADT довольно громоздок и не выглядит как базовый код на Haskell. Таким образом, Template Haskell предоставляет более классический вид синтаксиса обратных цитат.