Опубликован: 19.09.2008 | Доступ: свободный | Студентов: 658 / 70 | Оценка: 4.50 / 5.00 | Длительность: 21:25:00
Лекция 10:

Синтаксический справочник

< Лекция 9 || Лекция 10: 123456 || Лекция 11 >

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 \to module modid [exports] where body
| body
body \to { impdecls ; topdecls }
| { impdecls }
| { topdecls }
impdecls \to impdecl1 ; ... ; impdecln (n>=1)

Перевод:

модуль \to module идентификатор-модуля [список-экспорта] where тело
| тело
тело \to { список-объявлений-импорта ; список-объявлений-верхнего-уровня }
| { список-объявлений-импорта }
| { список-объявлений-верхнего-уровня }
список-объявлений-импорта \to объявление-импорта1 ; ... ; объявление-импортаn (n>=1)
exports \to ( export1 , ... , exportn [ , ] ) (n>=0)
export \to qvar
| qtycon [(..) | ( cname1 , ... , cnamen )] (n>=0)
| qtycls [(..) | ( qvar1 , ... , qvarn )] (n>=0)
| module modid

Перевод:

список-экспорта \to ( экспорт1 , ... , экспортn [ , ] ) (n>=0)
экспорт \to квалифицированная-переменная
| квалифицированный-конструктор-типа [(..) | ( c-имя1 , ... , c-имяn )] (n>=0)
| квалифицированный-класс-типа [(..) | ( квалифицированная-переменная1 , ... , квалифицированная-переменнаяn )] (n>=0)
| module идентификатор-модуля
impdecl \to import [qualified] modid [as modid] [impspec]
| (пустое объявление)
impspec \to ( import1 , ... , importn [ , ] ) (n>=0)
| hiding ( import1 , ... , importn [ , ] ) (n>=0)
import \to var
| tycon [ (..) | ( cname1 , ... , cnamen )] (n>=0)
| tycls [(..) | ( var1 , ... , varn )] (n>=0)
cname \to var | con

Перевод:

объявление-импорта \to import [qualified] идентификатор-модуля [ as идентификатор-модуля] [спецификатор-импорта]
| (пустое объявление)
спецификатор-импорта \to ( импорт1 , ... , импортn [ , ] ) (n>=0)
| hiding ( импорт1 , ... , импортn [ , ] ) (n>=0)
импорт \to переменная
| конструктор-типа [ (..) | ( c-имя1 , ... , c-имяn )] (n>=0)
| класс-типа [(..) | ( переменная1 , ... , переменнаяn )] (n>=0)
c-имя \to переменная | конструктор
topdecls \to topdecl1 ; ... ; topdecln (n>=0)
topdecl \to type simpletype = type
| data [context =>] simpletype = constrs [deriving]
| newtype [context =>] simpletype = newconstr [deriving]
| class [scontext =>] tycls tyvar [where cdecls]
| instance [scontext =>] qtycls inst [where idecls]
| default (type1 , ... , typen) (n>=0)
| decl

Перевод:

список-объявлений-верхнего-уровня \to объявление-верхнего-уровня1 ; ... ; объявление-верхнего-уровняn (n>=1)
объявление-верхнего-уровня \to type простой-тип = тип
| data [контекст \Rightarrow ] простой-тип = список-конструкций [ deriving -инструкция]
| newtype [контекст \Rightarrow ] простой-тип = новая-конструкция [ deriving -инструкция]
| class [простой-контекст \Rightarrow ] класс-типа переменная-типа [ where список-объявлений-классов]
| instance [простой-контекст \Rightarrow ] квалифицированный-класс-типа экземпляр [ where список-объявлений-экземпляров]
| default (тип1 , ... , типn) (n>=0)
| объявление
decls \to { decl1 ; ... ; decln } (n>=0)
decl \to gendecl
| (funlhs | pat0) rhs
cdecls \to { cdecl1 ; ... ; cdecln } (n>=0)
cdecl \to gendecl
| (funlhs | var) rhs
idecls \to { idecl1 ; ... ; idecln } (n>=0)
idecl \to (funlhs | var) rhs
| (empty)
gendecl \to vars :: [context =>] type (сигнатура типа)
| fixity [integer] ops ( infix -объявление)
| (пустое объявление)
ops \to op1 , ... , opn (n>=1)
vars \to var1 , ..., varn (n>=1)
fixity \to infixl | infixr | infix

Перевод:

список-объявлений \to { объявление1 ; ... ; объявлениеn } (n>=0)
объявление \to общее-объявление
| (левая-часть-функции | образец0) правая-часть
список-объявлений-классов \to { объявление-класса1 ; ... ; объявление-классаn } (n>=0)
объявление-класса \to общее-объявление
| (левая-часть-функции | переменная) правая-часть
список-объявлений-экземпляров \to { объявление-экземпляра1 ; ... ; объявление-экземпляраn } (n>=0)
объявление-экземпляра \to (левая-часть-функции | переменная) правая-часть
| (пусто)
общее-объявление \to список-переменных :: [контекст \Rightarrow ] тип (сигнатура типа)
| ассоциативность [целый-литерал] список-операторов ( infix -объявление)
| (пустое объявление)
список-операторов \to оператор1 , ... , операторn (n>=1)
список-переменных \to переменная1 , ... , переменнаяn (n>=1)
ассоциативность \to infixl | infixr | infix
type \to btype [-> type] (тип функции)
btype \to [btype] atype (наложение типов)
atype \to gtycon
| tyvar
| ( type1 , ... , typek ) (тип кортежа, k>=2 )
| [ type ] (тип списка)
| ( type ) (конструктор в скобках)
gtycon \to gtycon
| () (тип объединения)
| [] (конструктор списка)
| ( \to ) (конструктор функции)
| (,{,}) (конструкторы кортежей)
context \to class
| ( class1 , ... , classn ) (n>=0)
class \to qtycls tyvar
| qtycls ( tyvar atype1 ... atypen ) (n>=1)
scontext \to simpleclass
| ( simpleclass1 , ... , simpleclassn ) (n>=0)
simpleclass \to qtycls tyvar

Перевод:

тип \to b -тип [ \to тип] (тип функции)
b -тип \to [ b -тип] a -тип (наложение типов)
a -тип \to общий-конструктор-типа
| переменная-типа
| ( тип1 , ... , типk ) (тип кортежа, k>=2 )
| [ тип ] (тип списка)
| ( тип ) (конструктор в скобках)
общий-конструктор-типа \to квалифицированный-конструктор-типа
| () (тип объединения)
| [] (конструктор списка)
| ( \to ) (конструктор функции)
| (,{,}) (конструкторы кортежей)
контекст \to класс
| ( класс1 , ... , классn ) (n>=0)
класс \to квалифицированный-класс-типа переменная-типа
| квалифицированный-класс-типа ( переменная-типа a-тип1 ... a-типn ) (n>=1)
простой-контекст \to простой-класс
| ( простой-класс1 , ... , простой-классn ) (n>=0)
простой-класс \to квалифицированный-класс-типа переменная-типа
< Лекция 9 || Лекция 10: 123456 || Лекция 11 >