Списковые включения (ZF-выражения) с нулевыми квалификаторами

Списковые включения (или ZF-выражения) включают в себя последовательность квалификаторов , которые могут быть генераторами или булевыми выражениями («выражения фильтра»), действующими как охранники.

Понимание списка без квалификатора — например,[1 | ]–(видимо) допустимо в Miranda (стр. 130), но недействительно в Haskell , (стр. 42) – я пробовал это вghciинтерпретатор– и (очевидно) недействителен в Clean.

(Конечно, мы могли бы имитировать это, добавивTrueохрана, например[1 | True]. Но это более подробно)

Примером использования спискового понимания без определителя в литературе 1 (стр. 134-136) является следующий пример эквационального рассуждения:

      [E | ] ++ L = [E] ++ L = (E:[]) ++ L = E:L

Почему разработчики языков программирования Haskell и Clean отказались от спискового понимания без квалификаторов? Есть ли что-то, что может вызвать плохое взаимодействие функций в этих языках, но не в Миранде?


Использованная литература:

  1. Саймон Л. Пейтон Джонс. 1Реализация языков функционального программирования . Прентис Холл. 1987.

  2. Отчет Haskell 98, 2раздел 3.11 «Понимание списков» . 1998.

  3. Питер Вентворт. 3Введение в функциональное программирование с использованием объятий . 2013.

  4. Ринус Пласмейер; Марко ван Экелен; Джон ван Гронинген. 4Отчет о чистом языке, версия 2.2 . 2011.

1 ответ

Я думаю, что очевидный ответ заключается в том, что нет технической причины запрещать включение списков с пустой последовательностью квалификаторов. Требование чисто синтаксическое. Так уж получилось, что в разделе 3.11 исходного отчета Haskell98 указана грамматика, которая требует, чтобы список квалификаторов был непустым, и правила трансляции, превращающие его в выражение ядра, предполагают, что это так. GHC подчиняется этой грамматике, поэтому такое выражение, как[ 10 | ]отклоняется с ошибкой синтаксического анализа.

С технической точки зрения, простое упрощение грамматики и добавление одного правила перевода:

      [ e | ] = [ e | True ]

обратился бы к этому.

Собственно, документация для GHC MonadComprehensionsрасширение фактически обеспечивает перевод для этого случая:

      [ e | ] = return e

а остальные правила перевода в основном предполагают, что случаи формы:

      [ e | q, Q ]

относятся к частному случаю:

      [ e | q ]

сQпринимается за пустое.

Как только вы пройдете парсер, остальная часть GHC отлично справится с этим особым случаем. В частности, если вы используете Template Haskell, чтобы обойти синтаксический анализатор и создать включение без квалификаторов, вы увидите, что оно оценивается так, как ожидалось. (Отдельные модули здесь необходимы из-за ограничения фазы TH.)

      --
-- EmptyComprehension.hs
--

module EmptyComprehension where

import Language.Haskell.TH

-- equivalent to "[ 10 | ]"
x :: ExpQ
x = compE [noBindS (litE (integerL 10))]


--
-- Test.hs
--

{-# LANGUAGE TemplateHaskell #-}

import EmptyComprehension

main = print $(x)  -- will print `[10]`

Что касается того, почему язык был разработан таким образом, я думаю, что это было либо недосмотром, либо, возможно, это было рассмотрено в какой-то момент, но синтаксис[10 | ]считалось слишком странным, чтобы допустить его.

В соответствующей заметке, пустоcaseтакже были запрещены исходным отчетом Haskell98, но затем разрешены черезEmptyCaseрасширение, когда было обнаружено, что они действительно могут быть полезны.

Я думаю, у вас могут возникнуть проблемы с убеждением кого-либо в том, что подобное расширение для понимания имеет смысл. В комментариях вы упоминаете автоматическую генерацию исходников, но этот случай легко обработать специально или добавить доп.Trueквалификатор для каждого всеобъемлющего (или, если вы создаете исходный код с помощью TemplateHaskell, просто обойдите ограничение напрямую).

Другие вопросы по тегам