# Глава 2. Модули Прежде чем приступить к изучению языка, пара слов об инфраструктуре. ## Stack Haskell — кроссплатформенный язык, работающий и в Linux, и в macOS, и даже в Windows. Устанавливается Haskell несколькими способами, но самый удобный из них — [The Haskell Tool Stack.](https://docs.haskellstack.org/en/stable/) Эта маленькая утилита — всё, что может понадобиться для работы с Haskell. Главное (но не единственное), что умеет делать `stack`, это: {#block-stack} 1. Разворачивать инфраструктуру. 2. Собирать проекты. 3. Устанавливать библиотеки. 4. Запускать тесты и бенчмарки. **Haskell-инфраструктура** — экосистема, краеугольным камнем которой является ранее упомянутый компилятор GHC. Haskell является компилируемым языком: приложение представляет собой обыкновенный исполняемый (англ. executable) файл. **Haskell-проект** — среда для создания приложений и библиотек. **Haskell-библиотеки** — кем-то написанные решения, спасающие нас от изобретения велосипедов. ## Создание инфраструктуры В результате работы этой команды на ваш компьютер будет установлена инфраструктура последней стабильной версии: ```shell stack setup ``` Жить всё это хозяйство будет в только что созданном каталоге `~/.stack/`. Именно поэтому устанавливать инфраструктуру для последующих Haskell-проектов уже не требуется: единожды развернули, используем всегда. ## Структура проекта Чтобы создать проект `real`, нужно выполнить команду: ```shell stack new real ``` В результате будет создан каталог real, внутри которого мы увидим это: {#block-project-structure} ``` . ├── app │   └── Main.hs ├── CHANGELOG.md ├── LICENSE ├── package.yaml ├── README.md ├── real.cabal ├── Setup.hs ├── src │   └── Lib.hs ├── stack.yaml └── test └── Spec.hs ``` Здесь `app/Main.hs` — главный модуль программы, `src/Lib.hs` — еще один модуль, `real.cabal` — сборочный конфиг проекта, `stack.yaml` — конфиг Stack. По умолчанию в `src/Lib.hs` уже присутствует функция с именем `someFunc`. Все, что она делает — выводит в консоль строку "someFunc". Чтобы запустить проект, нужно перейти в его директорию и выполнить команду: ```shell stack build ``` В результате сборки появится файл `real-exe`. Располагается он внутри скрытого каталога `.stack-work` в корне проекта. Чтобы сразу его запустить, не копаясь во внутренностях этого скрытого каталога, используем команду: ```bash stack exec real-exe ``` ``` someFunc ``` Команда `stack exec` запускает программу (в данном случае `real-exe`) внутри `stack`-окружения. В одной из последующих глав я подробнее расскажу об этом окружении. Так выглядит создание и запуск Haskell-проекта, выводящего в консоль строку "someFunc". Но как же это работает? Пришла пора познакомиться с фундаментальной единицей проекта — модулем. ## Модули: знакомство Haskell-проект состоит из модулей. Модулем называется файл, содержащий исходный Haskell-код. Один файл — один модуль. Расширение `.hs` — стандартное расширения для модулей. В Haskell нет понятия «заголовочный файл»: каждый из модулей рассматривается как самостоятельная единица проекта, содержащая в себе разные полезные вещи. А чтобы воспользоваться этими вещами, необходимо один модуль импортировать в другой. Так выглядит содержимое модуля `src/Lib.hs` в проекте, созданном с помощью вызова `stack new`: ```haskell module Lib ( someFunc ) where someFunc :: IO () someFunc = putStrLn "someFunc" ``` На строке 1 объявлено, что имя этого модуля — `Lib`. Далее в круглых скобках указан интерфейс данного модуля, то есть та его часть, которая видна всему миру. В данном случае это единственная функция `someFunc`. Объявление и определение `someFunc` идёт далее на строках 5 и 6, вслед за ключевым словом `where`. Синтаксис объявления и определения функции мы разберём тщательнейшим образом в следующих главах. А пока обратите внимание, что для вывода строки "someFunc" в консоль используется встроенная функция `putStrLn` (**put** a **Str**ing followed by a new **L**i**n**e). А вот так выглядит модуль `app/Main.hs`: ```haskell {.example_for_playground} module Main where import Lib main :: IO () main = someFunc ``` Это модуль `Main`, главный модуль нашего приложения, ведь именно здесь определена функция `main`. С помощью директивы `import` мы включаем сюда модуль `Lib` и можем работать с содержимым этого модуля. Запомните модуль `Main`, с ним мы будем работать чаще всего. Все примеры исходного кода, которые вы увидите в этом курсе, живут именно в модуле `Main`, если не оговорено иное. Это же касается кода, который вы будете писать для решения задач. Все модули в наших проектах можно разделить на две части: те, которые мы берём из библиотек и те, которые мы создали сами. Библиотеки — это уже кем-то написанные решения, в последующих главах мы познакомимся со многими из них. Среди библиотек следует выделить одну, так называемую стандартную библиотеку. Модули из стандартной библиотеки мы начнём использовать уже в ближайших главах. А одна из глав будет полностью посвящена рассказу о библиотеках: из неё мы подробно узнаем, откуда берутся библиотеки и как их можно использовать. Как вы заметили, имена файлов с исходным кодом начинаются с большой буквы: `app/Main.hs` и `src/Lib.hs`. Строго говоря, это необязательно, можно и с маленькой буквы, однако для гармонии с именем модуля лучше придерживаться общепринятой практики и называть файл модуля по имени самого модуля: ``` app/Main.hs -> module Main ... src/Lib.hs -> module Lib ... ``` Создайте модуль `Main`, функция `main` которого выводит в консоль строку "Hello Haskell!". {.task_text} Для вывода строки воспользуйтесь функцией `putStrLn`. Синтаксис применения функции такой: имя функции и отделенный от него пробелом аргумент. {.task_text} Модуль `Main` не должен ничего импортировать. {.task_text} ```haskell {.task_source #haskell_chapter_0020_task_0010} ``` Вначале объявите модуль `Main`. Затем заведите функцию `main`, в теле которой к строке "Hello Haskell!" применяется функция `putStrLn`. {.task_hint} ```haskell {.task_answer} module Main where main :: IO () main = putStrLn "Hello Haskell!" ``` ## Для любопытных До появления `stack` основным способом установки Haskell была так называемая [Haskell Platform](https://www.haskell.org/platform/). Однако именно `stack` является предпочтительным путём в мир Haskell, особенно для новичков. Его настолько полюбили, что последние версии Haskell Platform включают в себя `stack` по умолчанию! И ещё. При создании проекта мы могли бы использовать схему `simple` вместо предлагаемой по умолчанию. Для этого проект нужно было создать командой: ```shell stack new real simple ``` где `simple` — имя схемы проекта. Дело в том, что команда `stack new` может создавать заготовки проектов для разных нужд. Простейшая из заготовок называется `simple`. В этом случае в проекте отсутствует модуль `src/Lib.hs` и директория с тестами, а есть лишь `src/Main.hs`: ``` . ├── CHANGELOG.md ├── LICENSE ├── README.md ├── real.cabal ├── Setup.hs ├── src │   └── Main.hs └── stack.yaml ``` Я рад, что вы познакомились с импортом уже сейчас, ведь в последующих главах мы будем постоянно использовать различные модули из многих библиотек.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!