Подтвердить что ты не робот

Конструктор Haskell tuple (GHC) и разделение между языком и его реализацией

Хаскелл снова взорвал мой разум, когда я понял, что

(x,y)

Является просто синтаксическим сахаром для

(,) x y

Естественно, я хотел расширить это на более крупные кортежи. Но

(,) x ((,) y z)

Дал мне

(x,(y,z))

Это не то, что я искал. По прихоти я попробовал

(,,) x y z

И это сработало, давая именно то, что я хотел:

(x,y,z)

Это подняло вопрос: как далеко вы можете это взять? К моему большому удивлению, казалось, нет предела. Все приведенные ниже действительные операторы:

(,)
(,,)
(,,,)
(,,,,)
--etc
(,,,,,,,,,,,,,,)
(,,,,,,,,,,,,,,,)
--etc
(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
--etc

Такое поведение удивительно и приводит к моему фактическому вопросу: это что-то, что можно эмулировать в моих собственных функциях? Или это просто особенность GHC для оператора кортежа? Я думаю, что это последний, поскольку я прочитал спецификацию haskell98, и iirc говорит, что реализациям необходимо определить оператор набора для до 15 элементов. В то время как GHC прошел весь свиньи и позволил вам сделать это до произвольных пределов.

Итак, можно ли определить это семейство операторов/функций из самой реализации haskell, используя только систему типов и существующие языковые функции (декларации, подписи типов, определения функций и т.д.)? И если да, то как? Или это невозможно, и вам нужно вместо этого взглянуть в компилятор, чтобы найти поддерживающую структуру для этой коллекции функций?

Это приводит к еще более общему вопросу: сколько из Haskell поддерживается самим Haskell, через определения типов и функций, декларации и т.д.; и насколько поддерживается компилятор/реализация? (Я знаю, что GHC был написан в Haskell, что не отвечает на вопрос)

То есть, если вы должны отказаться от стандартных библиотек (включая прелюдию) и делать все с нуля в сыром Haskell; можно ли построить полную реализацию, которая обладает всеми функциями GHC, используя только тот минимальный набор функций? Каков минимальный набор языковых функций, которые вам нужны для создания реализации haskell с использованием Haskell? Смогу ли я отказаться от прелюдии, а затем полностью перестроить ее вручную из GHC? Если вы откажетесь от прелюдии и никогда ничего не импортируете, что осталось для вас работать?

Может показаться, что я задаю миллион вопросов, но они действительно все пытаются спросить одно и то же с другой формулировкой. Дайте ему ваш лучший выстрел SO!

4b9b3361

Ответ 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, являющийся очевидным примером, - который вы не можете заменить вообще, потому что они подключены непосредственно к чему-то во время выполнения которую вы не можете заменить.