Привет, мир!
До сих пор для того, чтобы протестировать наши функции, мы загружали их в интерпретатор GHCi. Там же мы изучали функции из стандартной библиотеки. Но теперь, спустя семь глав, мы наконец-то собираемся написать первую программу на языке Haskell! Ура! И, конечно же, это будет старый добрый шедевр «Привет, мир».
Итак, для начинающих: наберите в вашем любимом текстовом редакторе строку
main = putStrLn "Привет, мир"
Мы только что определили имя main; в нём мы вызываем функцию putStrLn с параметром "Привет, мир". На первый взгляд, ничего необычного, но это не так: мы убедимся в этом через несколько минут. Сохраните файл как helloworld.hs.
Сейчас мы собираемся сделать то, чего ещё не пробовали делать. Мы собираемся скомпилировать нашу программу! Я даже разволновался!.. Откройте ваш терминал, перейдите в папку с сохранённым файлом helloworld.hs и выполните следующую команду:
$ ghc helloworld
[1 of 1] Compiling Main ( helloworld.hs, helloworld.o )
Linking helloworld …
О’кей! При некотором везении вы получите нечто похожее и теперь можете запустить свою программу, вызвав ./helloworld.
$ ./helloworld
Привет, мир
ПРИМЕЧАНИЕ. Если вы используете Windows, то вместо выполнения команды ./helloworld просто запустите файл helloworld.exe.
Ну вот и наша первая программа, которая печатает что-то на терминале! Банально до невероятности!
Давайте изучим более подробно, что же мы написали. Сначала посмотрим на тип функции putStrLn:
ghci> :t putStrLn
putStrLn :: String -> IO ()
ghci> :t putStrLn "Привет, мир"
putStrLn "Привет, мир" :: IO ()
Тип putStrLn можно прочесть таким образом: putStrLn принимает строку и возвращает действие ввода-вывода (I/O action) с результирующим типом () (это пустой кортеж). Действие ввода-вывода – это нечто вызывающее побочные эффекты при выполнении (обычно чтение входных данных или печать на экране); также действие может возвращать некоторые значения. Печать строки на экране не имеет какого-либо значимого результата, поэтому возвращается значение ().
ПРИМЕЧАНИЕ. Пустой кортеж имеет значение (), его тип – также ().
Когда будет выполнено действие ввода-вывода? Вот для чего нужна функция main. Операции ввода-вывода выполняются, если мы поместим их в функцию main и запустим нашу программу.