>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 должен находиться в той же папке, что и импортирующая его программа.
Модулям можно придать иерархическую структуру. Каждый модуль может иметь несколько подмодулей, которые в свою очередь также могут содержать подмодули. Давайте разделим наш модуль >Geometry
таким образом, чтобы в него входили три подмодуля, по одному на каждый тип объекта.
Сначала создадим папку с именем Geometry. В этой папке мы разместим три файла: Sphere.hs, Cuboid.hs и Cube.hs. Посмотрим, что должно находиться в каждом файле.
Вот содержимое файла Sphere.hs:
>module Geometry.Sphere
>( volume
>, area
>) where
>volume :: Float –> Float
>volume radius = (4.0 / 3.0) * pi * (radius 3)
>area :: Float –> Float
>area radius = 4 * pi * (radius 2)
Файл Cuboid.hs выглядит так:
>module Geometry.Cuboid
>( volume
>, area
>) where
>volume :: Float –> Float –> Float –> Float
>volume a b c = rectArea a b * c
>area :: Float –> Float –> Float –> Float
>area a b c = rectArea a b * 2 + rectArea a c * 2 + rectArea c b * 2
>rectArea :: Float –> Float –> Float
>rectArea a b = a * b
А вот и содержимое файла Cube.hs:
>module Geometry.Cube