Прогоняем код на Haskell через собственный препроцессор
16 августа 2013
Я тут читаю «Happstack Crashcourse» и нашел в главе о шаблонизаторах упоминание одной интересной возможности GHC. Оказывается, в исходном коде можно указывать дополнительные ключи, которые будут переданы GHC при компиляции программы, в том числе ключи, позволяющие прогнать код через произвольный препроцессор.
Допустим, мы хотим захардкодить время компиляции программы. Или ее версию, или еще что-нибудь — не суть важно. Напишем небольшой скрипт на Perl:
use strict;
use warnings;
my $localtime = localtime();
my ($fname, $input, $output) = @ARGV;
open my $fin, '<', $input or die $!;
open my $fout, '>', $output or die $!;
while(<$fin>) {
s/__LOCALTIME__/$localtime/g;
print $fout $_;
}
close $fin;
close $fout;
Сохраним его где-нибудь в $PATH с именем localtime_replace и скажем chmod u+x
. Как видите, скрипт принимает три параметра — имя оригинального файла, имя входного файла и имя выходного файла. Скрипт открывает входной файл, заменяем в нем строки «__LOCALTIME__» на текущее время и сохраняет результат в выходном файле.
Затем создадим файл test.hs следующего содержания:
main = putStrLn "Localtime: __LOCALTIME__"
Директива OPTIONS_GHC позволяет указать ключи, которые будут переданы GHC при компиляции программы. Описание всех ключей можно найти в «The Glorious Glasgow Haskell Compilation System User’s Guide». Интересующие нас в данный момент ключи описаны в разделе 4.12.4. Флаг -F говорит заюзать препроцессор, а ключ -pgmF указывает программу, которую следует использовать в качестве препроцессора. Также имеется ключ -optF, позволяющий передать препроцессору дополнительные аргументы. Эти аргументы будут переданы после имени выходного файла.
Проверяем:
ghci> main
Localtime: Thu Aug 15 22:50:04 2013
ghci> :q
Препроцессинг открывает перед нами много новых возможностей. Например, он активно используется в шаблонизаторе HSP, позволяющем использовать синтаксис XML прямо в исходном коде на Haskell. Однако, в силу понятных причин, использовать препроцессинг нужно с большой осторожностью.
Дополнение: Мои первые эксперименты с Template Haskell
Метки: Haskell, Функциональное программирование.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.