Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [47]

By Root 479 0
c b * 2

rectArea :: Float -> Float -> Float

rectArea a b = a * b

This is pretty standard geometry, but there are a few items to note. One is that because a cube is only a special case of a cuboid, we define its area and volume by treating it as a cuboid whose sides are all of the same length. We also define a helper function called rectArea, which calculates a rectangle’s area based on the lengths of its sides. It’s rather trivial because it’s just multiplication. Notice that we used it in our functions in the module (in cuboidArea and cuboidVolume), but we didn’t export it! This is because we want our module to present just functions for dealing with three-dimensional objects.

When making a module, we usually export only those functions that act as a sort of interface to our module so that the implementation is hidden. People who use our Geometry module don’t need to concern themselves with functions that we don’t export. We can decide to change those functions completely or delete them in a newer version (we could delete rectArea and just use * instead), and no one will mind, because we didn’t export them in the first place.

To use our module, we just do this:

import Geometry

However, Geometry.hs must be in the same folder as the module that’s importing it.

Hierarchical Modules


Modules can also be given a hierarchical structure. Each module can have a number of submodules, which can have submodules of their own. Let’s section our geometry functions so that Geometry is a module that has three submodules: one for each type of object.

First, we’ll make a folder called Geometry. In it, we’ll place three files: Sphere.hs, Cuboid.hs, and Cube.hs. Let’s look at what each of the files contains.

Here are the contents of 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)

The Cuboid.hs file looks like this:

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

And our last file, Cube.hs, has these contents:

module Geometry.Cube

( volume

, area

) where

import qualified Geometry.Cuboid as Cuboid

volume :: Float -> Float

volume side = Cuboid.volume side side side

area :: Float -> Float

area side = Cuboid.area side side side

Notice how we placed Sphere.hs in a folder called Geometry, and then defined the module name as Geometry.Sphere. We did the same for the cube and cuboid objects. Also notice how in all three sub-modules, we defined functions with the same names. We can do this because they’re in separate modules.

So, now we can do this:

import Geometry.Sphere

And then we can call area and volume, and they’ll give us the area and volume for a sphere.

If we want to juggle two or more of these modules, we need to do qualified imports because they export functions with the same names. Here’s an example:

import qualified Geometry.Sphere as Sphere

import qualified Geometry.Cuboid as Cuboid

import qualified Geometry.Cube as Cube

And then we can call Sphere.area, Sphere.volume, Cuboid.area, and so on, and each will calculate the area or volume for its corresponding object.

The next time you find yourself writing a file that’s really big and has a lot of functions, look for functions that serve some common purpose and consider putting them in their own module. Then you’ll be able to just import your module the next time you’re writing a program that requires some of the same functionality.

Chapter 7. Making Our Own Types and Type Classes

So far, we’ve run into a lot of data types: Bool, Int, Char, Maybe, and so on. But how do we make our own? In this chapter, you’ll learn how to create custom types and put them to work!

Defining a New Data Type

One way to make our own type is to use the

Return Main Page Previous Page Next Page

®Online Book Reader