Ответ 1
Увы, в кортежах нет магии. Здесь реализация GHC использует, и дать вам некоторое представление о том, что происходит здесь, источник для последнего определения:
data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__
= (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__
... да.
Итак, можно ли определить это семейство операторов/функций из самой реализации haskell, используя только систему типов и существующие языковые функции (декларации, подписи типов, определения функций и т.д.)? И если да, то как? Или это невозможно, и вам нужно вместо этого взглянуть в компилятор, чтобы найти поддерживающую структуру для этой коллекции функций?
Нет, нет способа определить такие кортежи, как это в общем виде. Общая картина является чисто синтаксической, ничего, что можно сделать рекурсивно в системе типов или иначе. Вы могли бы сгенерировать такие определения с помощью шаблона Haskell, конечно же, но вы все равно должны генерировать каждый индивидуально с помощью манипуляции с строкой, чтобы создать имя, а не использовать какую-либо общую структуру.
Также есть вопрос, что синтаксис кортежа встроен, а не то, что можно имитировать, но это отдельная проблема. Вы можете представить себе такие типы, как:
data Tuple2 a b = Tuple2 a b
data Tuple3 a b c = Tuple3 a b c
... и т.д., которые не используют специальный синтаксис, но все еще не могут быть определены в общих чертах по причинам выше.
Это приводит к еще более общему вопросу: сколько из Haskell поддерживается самим Haskell, через определения типов и функций, декларации и т.д.; и насколько поддерживается компилятор/реализация? (Я знаю, что GHC был написан в Haskell, что не отвечает на вопрос)
Почти все это определено в Haskell. Некоторые вещи имеют специальный синтаксис, который вы не можете имитировать, но в большинстве случаев это распространяется только на то, что компилятор уделяет особое внимание определенным определениям. В противном случае нет никакой разницы между этим:
data [] a = [] | a : [a]
... и любой эквивалентный тип, который вы сами определяете.
То есть, если вы должны отказаться от стандартных библиотек (включая прелюдию) и делать все с нуля в сыром Haskell; можно ли построить полную реализацию, которая обладает всеми функциями GHC, используя только тот минимальный набор функций? Каков минимальный набор языковых функций, которые вам нужны для создания реализации haskell с использованием Haskell? Смогу ли я отказаться от прелюдии, а затем полностью перестроить ее вручную из GHC? Если вы откажетесь от прелюдии и никогда ничего не импортируете, что осталось для вас работать?
Вам может показаться, что это полезно для чтения расширений GHC NoImplicitPrelude и RebindableSyntax, которые позволяют, среди прочего, изменять определения, используемые для интерпретации нотации do
как обрабатываются числовые литералы, что делает синтаксис if then else
и т.д.
Достаточно сказать, что очень, очень мало нельзя переоценить. Большинство вещей, которые не могут быть только специальными из-за синтаксиса, и могут быть заменены эквивалентными вещами (например, списками и кортежами, выше).
В конце концов существует ограниченный набор вещей, которые имеют очень особое поведение - тип IO
, являющийся очевидным примером, - который вы не можете заменить вообще, потому что они подключены непосредственно к чему-то во время выполнения которую вы не можете заменить.