Синтаксический справочник
9.4 Грамотные комментарии
Соглашение о "грамотных комментариях", впервые разработанное Ричардом Бердом (Richard Bird) и Филиппом Уодлером (Philip Wadler) для Orwell, и позаимствованное в свою очередь Дональдом Кнутом (Donald Knutd) для "грамотного программирования", является альтернативным стилем программирования исходного кода на Haskell . Грамотный стиль поощряет комментарии, создавая их по умолчанию. Строка, в которой ">" является первым символом, интерпретируется как часть программы; все остальные строки являются комментарием.
Текст программы восстанавливается путем выбора только тех строк, которые начинаются с ">", и замены первого ">" на пробел. В полученном тексте размещение и комментарии применяются в точности как описано в главе "9" .
Чтобы охватить некоторые случаи, где можно по ошибке пропустить ">", возникнет ошибка, если строка программы появится рядом с непробельной строкой комментария; строка рассматривается как пробельная, если она состоит только из пробельных символов.
Условно на стиль комментария указывает расширение файла: ".hs" указывает на обычный файл на Haskell, а ".lhs" указывает на файл с грамотным Haskell. С использованием этого стиля простая программа вычисления факториала могла бы выглядеть так:
Эта грамотная программа запрашивает у пользователя число и выводит на экран факториал этого числа: > main :: IO () > main = do putStr "Введите число: " > l <- readLine > putStr "n!= " > print (fact (read l)) Это программа вычисления факториала. > fact :: Integer -> Integer > fact 0 = 1 > fact n = n * fact (n-1)
Альтернативный стиль грамотного программирования особенно подходит для использования вместе с системой обработки текста LaTeX. По этому соглашению только те части грамотной программы, которые полностью заключены между разделителями \begin{code}...\end{code}, рассматриваются как текст программы; все остальные строки --- комментарии. Более точно:
- Код программы начинается на первой строке, следующей за строкой, которая начинает \begin{code}.
- Код программы заканчивается сразу перед последующей строкой, которая начинает \end{code} (конечно, игнорируя строковые литералы).
Нет необходимости вставлять дополнительные пустые строки до или после этих разделителей, хотя со стилистической точки зрения это может быть желательно. Например,
\documentstyle{article} \begin{document} \section{Introduction}
Это тривиальная программа, которая выводит первые 20 факториалов.
\begin{code} main :: IO () main = print [ (n, product [1..n]) | n <- [1..20]] \end{code} \end{document}
Этот стиль использует то же расширение файла. Нежелательно смешивать эти два стиля в одном файле.
9.5 Контекстно-свободный синтаксис
module | module modid [exports] where body | ||
| | body | ||
body | { impdecls ; topdecls } | ||
| | { impdecls } | ||
| | { topdecls } | ||
impdecls | impdecl1 ; ... ; impdecln | (n>=1) |
Перевод:
модуль | module идентификатор-модуля [список-экспорта] where тело | ||
| | тело | ||
тело | { список-объявлений-импорта ; список-объявлений-верхнего-уровня } | ||
| | { список-объявлений-импорта } | ||
| | { список-объявлений-верхнего-уровня } | ||
список-объявлений-импорта | объявление-импорта1 ; ... ; объявление-импортаn | (n>=1) |
exports | ( export1 , ... , exportn [ , ] ) | (n>=0) | |
export | qvar | ||
| | qtycon [(..) | ( cname1 , ... , cnamen )] | (n>=0) | |
| | qtycls [(..) | ( qvar1 , ... , qvarn )] | (n>=0) | |
| | module modid |
Перевод:
список-экспорта | ( экспорт1 , ... , экспортn [ , ] ) | (n>=0) | |
экспорт | квалифицированная-переменная | ||
| | квалифицированный-конструктор-типа [(..) | ( c-имя1 , ... , c-имяn )] | (n>=0) | |
| | квалифицированный-класс-типа [(..) | ( квалифицированная-переменная1 , ... , квалифицированная-переменнаяn )] | (n>=0) | |
| | module идентификатор-модуля |
Перевод:
Перевод:
Перевод:
type | btype [-> type] | (тип функции) | |
btype | [btype] atype | (наложение типов) | |
atype | gtycon | ||
| | tyvar | ||
| | ( type1 , ... , typek ) | (тип кортежа, k>=2 ) | |
| | [ type ] | (тип списка) | |
| | ( type ) | (конструктор в скобках) | |
gtycon | gtycon | ||
| | () | (тип объединения) | |
| | [] | (конструктор списка) | |
| | ( ) | (конструктор функции) | |
| | (,{,}) | (конструкторы кортежей) | |
context | class | ||
| | ( class1 , ... , classn ) | (n>=0) | |
class | qtycls tyvar | ||
| | qtycls ( tyvar atype1 ... atypen ) | (n>=1) | |
scontext | simpleclass | ||
| | ( simpleclass1 , ... , simpleclassn ) | (n>=0) | |
simpleclass | qtycls tyvar |
Перевод:
тип | b -тип [ тип] | (тип функции) | |
b -тип | [ b -тип] a -тип | (наложение типов) | |
a -тип | общий-конструктор-типа | ||
| | переменная-типа | ||
| | ( тип1 , ... , типk ) | (тип кортежа, k>=2 ) | |
| | [ тип ] | (тип списка) | |
| | ( тип ) | (конструктор в скобках) | |
общий-конструктор-типа | квалифицированный-конструктор-типа | ||
| | () | (тип объединения) | |
| | [] | (конструктор списка) | |
| | ( ) | (конструктор функции) | |
| | (,{,}) | (конструкторы кортежей) | |
контекст | класс | ||
| | ( класс1 , ... , классn ) | (n>=0) | |
класс | квалифицированный-класс-типа переменная-типа | ||
| | квалифицированный-класс-типа ( переменная-типа a-тип1 ... a-типn ) | (n>=1) | |
простой-контекст | простой-класс | ||
| | ( простой-класс1 , ... , простой-классn ) | (n>=0) | |
простой-класс | квалифицированный-класс-типа переменная-типа |