Модуль Geometry
Давайте разберём процесс создания модулей на простом примере. Создадим модуль, который содержит функции для вычисления объёма и площади поверхности нескольких геометрических фигур. И начнём с создания файла Geometry.hs.
В начале модуля указывается его имя. Если мы назвали файл Geometry.hs, то имя нашего модуля должно быть Geometry. Затем следует перечислить экспортируемые функции, после чего мы можем писать сами функции:
module Geometry
( sphereVolume
, sphereArea
, cubeVolume
, cubeArea
, cuboidArea
, cuboidVolume
) where
Как видите, мы будем вычислять площади и объёмы для сфер (sphere), кубов (cube) и прямоугольных параллелепипедов (cuboid). Сфера – это круглая штука наподобие грейпфрута, куб – квадратная штука, похожая на кубик Рубика, а прямоугольный параллелепипед – точь-в-точь пачка сигарет. (Дети, курить вредно!)
Продолжим и определим наши функции:
module Geometry
( sphereVolume , sphereArea
, cubeVolume
, cubeArea
, cuboidArea
, cuboidVolume
) where
sphereVolume :: Float –> Float
sphereVolume radius = (4.0 / 3.0) * pi * (radius 3)
sphereArea :: Float –> Float
sphereArea radius = 4 * pi * (radius 2)
cubeVolume :: Float –> Float
cubeVolume side = cuboidVolume side side side
cubeArea :: Float –> Float
cubeArea side = cuboidArea side side side
cuboidVolume :: Float –> Float –> Float –> Float
cuboidVolume a b c = rectArea a b * c
cuboidArea :: Float –> Float –> Float –> Float
cuboidArea a b c = rectArea a b * 2 + rectArea a c * 2 + rectArea c b * 2
rectArea :: Float –> Float –> Float
rectArea a b = a * b
Довольно стандартная геометрия, но есть несколько вещей, на которые стоит обратить внимание. Так как куб – это разновидность параллелепипеда, мы определили его площадь и объём, трактуя куб как параллелепипед с равными сторонами. Также мы определили вспомогательную функцию rectArea, которая вычисляет площадь прямоугольника по его сторонам. Функция очень проста – она просто перемножает стороны. Заметьте, мы используем функцию rectArea в функциях модуля (а именно в функциях cuboidArea и cuboidVolume), но не экспортируем её, так как хотим создать модуль для работы только с трёхмерными объектами.
При создании модуля мы обычно экспортируем только те функции, которые служат интерфейсом нашего модуля, и скрываем реализацию. Использующий наш модуль человек ничего не должен знать о тех функциях, которые мы не экспортируем. Мы можем полностью их поменять или удалить в следующей версии (скажем, удалить определение функции rectArea и просто использовать умножение), и никто не будет против – в первую очередь потому, что эти функции не экспортируются.
Чтобы использовать наш модуль, запишем:
import Geometry
Файл Geometry.hs должен находиться в той же папке, что и импортирующая его программа.