Модуль 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 должен находиться в той же папке, что и импортирующая его программа.