diff --git a/app/MainPng.hs b/app/MainPng.hs
deleted file mode 100644
--- a/app/MainPng.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main where
-
-import GIS.Exe.OptCairo
-
-main :: IO ()
-main = exec
diff --git a/cabal.project.local b/cabal.project.local
--- a/cabal.project.local
+++ b/cabal.project.local
@@ -1,4 +1,4 @@
-constraints: hgis +development
+constraints: hgis +development +cairo
 with-compiler: ghc-8.2.2
 optimization: 2
 documentation: true
diff --git a/hgis.cabal b/hgis.cabal
--- a/hgis.cabal
+++ b/hgis.cabal
@@ -1,14 +1,14 @@
 cabal-version: 1.18
 name: hgis
-version: 0.1.3.8
+version: 1.0.0.0
 license: BSD3
 license-file: LICENSE
 copyright: Copyright: (c) 2016-2018 Vanessa McHale
 maintainer: vamchale@gmail.com
 author: Vanessa McHale
-synopsis: Package and command-line for GIS with Haskell
+synopsis: Library and for GIS with Haskell
 description:
-    Package containting functions to make graphs, read
+    Package containing functions to make graphs, read
     shapefiles, and compute areas/perimeters of
     geographic features.
 category: Web
@@ -21,13 +21,8 @@
                  src/depends/readshp/LICENSE
 
 source-repository head
-    type: git
-    location: https://github.com/vmchale/hgis
-
-flag llvm-fast
-    description:
-        Enable build with llvm backend
-    default: False
+    type: darcs
+    location: https://hub.darcs.net/vmchale/hgis
 
 flag development
     description:
@@ -35,23 +30,24 @@
     default: False
     manual: True
 
+flag cairo
+    description:
+        Enable build using cairo backend, allowing generation of PNGs
+    default: True
+
 library
     exposed-modules:
-        GIS.Exe.Opt
-        GIS.Exe.OptCairo
+        GIS.Math.Projections
         GIS.Math.Spherical
-        GIS.Graphics.PlotPNG
-        GIS.Graphics.PlotSVG
         GIS.Hylo
-        GIS.Math.Projections
+        GIS.Graphics.PlotSVG
     hs-source-dirs: src src/depends/readshp
     other-modules:
+        GIS.Graphics.Types
         GIS.Math.Utils
         GIS.Utils
         GIS.Graphics.Plot
-        GIS.Graphics.Types
         GIS.Types
-        GIS.Exe.Parser
         Geometry.Shapefile
         Geometry.Shapefile.MergeShpDbf
         Geometry.Shapefile.ReadDbf
@@ -63,9 +59,7 @@
     ghc-options: -Wall
     build-depends:
         base >=4.7 && <5,
-        optparse-applicative -any,
         Chart -any,
-        Chart-cairo -any,
         Chart-diagrams -any,
         lens -any,
         composition-prelude >=1.1.0.1,
@@ -79,25 +73,13 @@
         filepath -any,
         monad-loops -any
     
-    if flag(development)
-        ghc-options: -Werror
-    
-    if impl(ghc >=8.0)
-        ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates
-
-executable hgis
-    main-is: MainPng.hs
-    hs-source-dirs: app
-    default-language: Haskell2010
-    ghc-options: -Wall
-    build-depends:
-        base >4.9 && <5,
-        hgis -any
+    if flag(cairo)
+        exposed-modules:
+            GIS.Graphics.PlotPNG
     
-    if flag(llvm-fast)
-        ghc-options: -threaded -rtsopts -with-rtsopts=-N -fllvm -optlo-O3
-    else
-        ghc-options: -threaded -rtsopts -with-rtsopts=-N
+    if flag(cairo)
+        build-depends:
+            Chart-cairo -any
     
     if flag(development)
         ghc-options: -Werror
diff --git a/src/GIS/Exe/Opt.hs b/src/GIS/Exe/Opt.hs
deleted file mode 100644
--- a/src/GIS/Exe/Opt.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-module GIS.Exe.Opt where
-
-import           Control.Lens
-import           Data.Semigroup
-import           GIS.Exe.Parser       hiding (projection)
-import           GIS.Graphics.PlotSVG
-import           GIS.Graphics.Types   hiding (projection)
-import           GIS.Hylo
-import           Options.Applicative
-import           System.Directory
-
-pick :: Program -> IO ()
-pick (Program (MapMaker outfile False projection) infile) = let p = pickProjection projection in
-    mkMapSVG outfile =<< districtToMapP p <$> getDistricts infile
-pick (Program (MapMaker _ True projection) infile) = let p = pickProjection projection in
-    makeFoldersSVG =<< districtToMapFilesP p <$> getDistricts infile
-pick (Program (MapLabel outfile False projection lensName) infile) = let p = pickProjection projection in
-    mkMapSVG outfile =<< districtToMapLensP p (pickLens lensName) <$> getDistricts infile -- FIXME make it work with -a (generate-all)
-pick _ = error "not yet implemented."
-
-exec :: IO ()
-exec = pick =<< execParser helpDisplay
-
-makeFoldersSVG :: [Map] -> IO ()
-makeFoldersSVG maps = do
-    createDirectoryIfMissing False "maps"
-    mapM_ (\m -> mkMapSVG ("maps/" <> view title m <> ".svg") m) maps
diff --git a/src/GIS/Exe/OptCairo.hs b/src/GIS/Exe/OptCairo.hs
deleted file mode 100644
--- a/src/GIS/Exe/OptCairo.hs
+++ /dev/null
@@ -1,43 +0,0 @@
--- | This contains the main program executable for the program when built with
--- the Cairo libary
-module GIS.Exe.OptCairo
-    ( -- * Data types
-    Program (..)
-    -- * Functions
-    , exec
-    ) where
-
-import           Control.Lens
-import           Data.Semigroup
-import           GIS.Exe.Parser       hiding (projection)
-import           GIS.Graphics.PlotPNG
-import           GIS.Graphics.Types   hiding (projection)
-import           GIS.Hylo
-import           Options.Applicative
-import           System.Directory
-
--- | Main executable; parses command line options and runs program
-exec :: IO ()
-exec = pick =<< execParser helpDisplay
-
--- | Execute the program with parsed command-line input
-pick :: Program -> IO ()
-pick (Program (MapMaker outfile False projection) infile) = let p = pickProjection projection in
-    mkMap outfile =<< districtToMapP p <$> getDistricts infile -- svg now idk?
-pick (Program (MapMaker _ True projection) infile) = let p = pickProjection projection in
-    makeFoldersPng =<< districtToMapFilesP p <$> getDistricts infile -- TODO fix this
-pick (Program (Computation comp Nothing) infile) = --slightly wrong but eh.
-    case comp of
-        "perimeter" -> putStrLn =<< districtPerimeter <$> getDistricts infile
-        "area" -> putStrLn =<< districtArea <$> getDistricts infile
-        "compactness" -> putStrLn =<< districtCompactness <$> getDistricts infile
-        _ -> putStrLn "computation not recognized"
-pick (Program (MapLabel outfile False _ lensName) infile) =
-    mkLensMap "" outfile (pickLens lensName) =<< getDistricts infile -- FIXME make it work with -a (generate-all) and make it not bind things together??
-pick _ = error "not yet supported."
-
--- | Make maps as png files.
-makeFoldersPng :: [Map] -> IO ()
-makeFoldersPng maps = do
-    createDirectoryIfMissing False "maps"
-    mapM_ (\m -> mkMapPng ("maps/" <> view title m <> ".png") m) maps
diff --git a/src/GIS/Exe/Parser.hs b/src/GIS/Exe/Parser.hs
deleted file mode 100644
--- a/src/GIS/Exe/Parser.hs
+++ /dev/null
@@ -1,107 +0,0 @@
-{-# LANGUAGE RankNTypes #-}
--- | This module contains the parser for the command-line options
-module GIS.Exe.Parser where
-
-import           Control.Lens         hiding (argument)
-import           Data.Monoid
-import           GIS.Math.Projections
-import           GIS.Types
-import           Options.Applicative
-
--- | Data type for one run of the program
-data Program = Program { com  :: Command
-                       , file :: FilePath -- "Path to dbf file"
-                       }
-
--- | Data type for the appropriate subcommand
-data Command = Computation { computation :: String , outputM :: Maybe FilePath }
-    | MapMaker { output :: FilePath , generateAll :: Bool , projection :: Maybe String }
-    | MapLabel { output :: FilePath , generateAll :: Bool , projection :: Maybe String , computatation :: String }
-
--- | Parses the `Program` data type
-program :: Parser Program
-program = Program
-    <$> hsubparser
-        ( command "compute" (info computationP ( progDesc "Compute perimeter, area, etc. of map" ))
-        <> command "map" (info mapMaker ( progDesc "Make a map from a shapefile database." ))
-        <> command "labelmap" (info mapLabelMaker ( progDesc "Make a map from a shapefile database, and label areas with relevant info" )))
-    <*> argument str
-            (metavar "SHAPEFILE"
-            <> help "Path to .shp file"
-            <> completer (bashCompleter "file -X '!*.shp' -o plusdirs"))
-
--- | Parses the `Command` datatype into a Computation
-computationP :: Parser Command
-computationP = Computation
-    <$> argument str
-        ( metavar "COMPUTATION"
-        <> help "which computation to perform, e.g. area, perimeter, etc." )
-    <*> optional (strOption  -- because it's a maybe filepath
-        ( long "output"
-        <> short 'o'
-        <> metavar "OUTPUT"
-        <> help "Where to write output" ))
-
--- | Parses the `Command` datatype into a map
-mapLabelMaker :: Parser Command
-mapLabelMaker = MapLabel
-    <$> strOption
-        (long "output"
-        <> short 'o'
-        <> metavar "OUTPUT"
-        <> help "Where to write the image/map" )
-    <*> switch
-        (long "generate-all"
-        <> short 'a'
-        <> help "Whether to generate a separate file for each object in the shapefile" )
-    <*> optional (strOption
-        (long "projection"
-        <> short 'p'
-        <> help "Which projection to use, e.g. mercator etc."))
-    <*> strOption
-        (long "label"
-        <> short 'p'
-        <> help "What aspect to label (area, perimeter, compactness)")
-
--- | Parses the `Command` datatype into a map
-mapMaker :: Parser Command
-mapMaker = MapMaker
-    <$> strOption
-        (long "output"
-        <> short 'o'
-        <> metavar "OUTPUT"
-        <> help "Where to write the image/map" )
-    <*> switch
-        (long "generate-all"
-        <> short 'a'
-        <> help "Whether to generate a separate file for each object in the shapefile" )
-    <*> optional (strOption
-        (long "projection"
-        <> short 'p'
-        <> help "Which projection to use, e.g. mercator etc."))
-
--- | display help if user enters e.g.
---
--- > hgis --help wrongcommand
-helpDisplay :: ParserInfo Program
-helpDisplay = info ( program <**> helper)
-    ( fullDesc
-    <> progDesc "GIS for Haskell. Can make maps, compute areas/perimeters for shapefiles."
-    <> header "hgis - GIS in Haskell" )
-
-pickLens :: String -> Lens' District Double
-pickLens "compactness" = compactness
-pickLens "perimeter"   = perimeter
-pickLens _             = error "must be one of 'compactness', 'perimeter'"
-
--- | Parse a `Maybe String` into the appropriate `Projection`, doing nothing for
--- a `Nothing`
-pickProjection :: Maybe String -> Projection
-pickProjection s = case s of
-    Just "mercator" -> mercator
-    Just "bonne"    -> bonne
-    Just "albers"   -> albers washingtonDC
-    Just "winkel3"  -> winkel3
-    Just "littow"   -> littow
-    Just _ -> error "unknown projection. try one of 'mercator', 'bonne', 'albers', 'winkel3', or 'littow'"
-    Nothing         -> id
diff --git a/src/GIS/Graphics/Plot.hs b/src/GIS/Graphics/Plot.hs
--- a/src/GIS/Graphics/Plot.hs
+++ b/src/GIS/Graphics/Plot.hs
@@ -1,11 +1,13 @@
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE RankNTypes      #-}
+{-# LANGUAGE RecordWildCards #-}
 
 -- | Module containing renderable objects and plots for our maps
 module GIS.Graphics.Plot where
 
+import           Control.Arrow
 import           Data.Colour.Names
 import           GIS.Graphics.Types            hiding (title)
-import           GIS.Math.Spherical
+import           GIS.Math.Utils
 import           GIS.Types
 import           GIS.Utils
 import           Graphics.Rendering.Chart
@@ -14,7 +16,9 @@
 -- | Given a map, return a `Renderable ()` for use with the
 -- """Graphics.Rendering.Char""" module.
 mkMapR :: Map -> Renderable ()
-mkMapR Map { _title = tit , _labelEntities = le , _labelledDistricts = points } = if le then mkRenderableLabelled tit points else mkRenderableLabelled tit $ fmap (over _2 (pure "")) points
+mkMapR Map{..} = if _labelEntities
+    then mkRenderableLabelled _title _labelledDistricts
+    else mkRenderableLabelled _title $ second (pure "") <$> _labelledDistricts
 
 mkRenderablePlots :: String -> [Plot Double Double] -> Renderable ()
 mkRenderablePlots title plots = toRenderable $
@@ -34,13 +38,13 @@
 
 -- | Set labels via a lens field.
 labelByLens :: (Show a) => Lens' District a -> [District] -> [([Polygon], String)]
-labelByLens lens districts = zip (fmap (view shape) districts) (fmap (show . view lens) districts)
+labelByLens lens districts = zip (fmap _shape districts) (fmap (show . view lens) districts)
 
 -- | Helper function to plot labels on a map. The ordinate will be plotted at
 -- the centroid of the abscissa, which may be outside the polygon if it is
 -- concave.
 plotLabels :: [([Polygon], String)] -> Plot Double Double
 plotLabels points = toPlot texts
-    where pairs = fmap (flatten . over _1 (shittyCentroid . concat)) points
+    where pairs = fmap (flatten . first (shittyCentroid . concat)) points
           fontStyle = font_size .~ 15 $ font_weight .~ FontWeightBold $ def
           texts = plot_annotation_values .~ pairs $ plot_annotation_style .~ fontStyle $ def
diff --git a/src/GIS/Hylo.hs b/src/GIS/Hylo.hs
--- a/src/GIS/Hylo.hs
+++ b/src/GIS/Hylo.hs
@@ -1,4 +1,6 @@
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE RankNTypes      #-}
+{-# LANGUAGE RecordWildCards #-}
+
 -- | Module to transform shapefiles.
 module GIS.Hylo where
 
@@ -13,7 +15,7 @@
 import           GIS.Graphics.Types
 import           GIS.Math.Projections
 import           GIS.Math.Spherical
-import           GIS.Types                      hiding (area, perimeter)
+import           GIS.Types                      hiding (area)
 import           GIS.Utils
 import           System.Directory
 
@@ -63,16 +65,18 @@
 getDistricts filepath = do
         dbfExists <- doesFileExist (stripExt filepath <> ".dbf")
         file <- if dbfExists then readShpWithDbf filepath else readShpFile filepath
-        let districtLabels = fromJust $ fmap labels $ mapM shpRecLabel . shpRecs $ file -- labels + field descriptions?
-        let shapes = fmap (getPolygon . fromJust . shpRecContents) . shpRecs $ file
-        let perimeters = fmap (totalPerimeter . getPolygon . fromJust . shpRecContents) . shpRecs $ file
-        let areas = fmap (fmap areaPolygon . getPolygon . fromJust . shpRecContents) . shpRecs $ file
-        let compacticity = fmap (relativeCompactness . concat . getPolygon . fromJust . shpRecContents) . shpRecs $ file
+        -- FIXME throw a real error.
+        let extract f = fmap (f . getPolygon . fromJust . shpRecContents) . shpRecs $ file
+            districtLabels = fromJust $ fmap labels $ traverse shpRecLabel . shpRecs $ file
+            shapes = extract id
+            perimeters = extract totalPerimeter
+            areas = extract (fmap areaPolygon)
+            compacticity = extract (relativeCompactness . concat)
         pure $ zipWith5 District shapes districtLabels perimeters areas compacticity
 
 -- | Helper function for extracting from shapefiles.
 getPolygon :: RecContents -> [Polygon]
-getPolygon RecPolygon { recPolPoints = pt }   = pt
-getPolygon RecPolygonM { recPolMPoints = pt } = pt
-getPolygon RecPolygonZ { recPolZPoints = pt } = pt
+getPolygon RecPolygon {..} = recPolPoints
+getPolygon RecPolygonM {..} = recPolMPoints
+getPolygon RecPolygonZ {..} = recPolZPoints
 getPolygon _ = error "shapefile contents not supported. please ensure the shapefile contains a list of polygons."
diff --git a/src/GIS/Math/Projections.hs b/src/GIS/Math/Projections.hs
--- a/src/GIS/Math/Projections.hs
+++ b/src/GIS/Math/Projections.hs
@@ -1,18 +1,32 @@
 -- | Module containing several useful projections for generating maps.
-module GIS.Math.Projections where
+module GIS.Math.Projections ( -- * Reference points
+                              washingtonDC
+                            , mecca
+                            -- * Projections
+                            , littow
+                            , craig
+                            , winkel3
+                            , mercator
+                            , bonne
+                            , albers
+                            -- * Helper functions
+                            , project
+                            , projectMap
+                            ) where
 
+import           Control.Arrow
 import           Control.Lens
 import           GIS.Graphics.Types
 import           GIS.Math.Utils
 import           GIS.Types
 
--- | For use as a reference point in certain projections.
+-- | For use as a reference point
 washingtonDC :: Point
-washingtonDC = over _2 radians $ over _1 radians (38.9072, -77.0369)
+washingtonDC = toRadians (38.9072, -77.0369)
 
--- | For use as a reference point with the Craig retroazimuthal projection
+-- | For use as a reference point
 mecca :: Point
-mecca = over _2 radians $ over _1 radians (21.3891, 39.8579)
+mecca = toRadians (21.3891, 39.8579)
 
 -- | Littow retroazimuthal + conformal projection
 littow :: Projection
@@ -20,14 +34,14 @@
     where referenceLong = radians 0
 
 -- | Craig retroazimuthal projection
--- (works on a subset of the world)
 craig :: Point -> Projection
 craig referencePoint (long, lat) = (long - referenceLong, y)
     where (referenceLong, referenceLat) = referencePoint
-          y = if long - referenceLong == 0 then expr else (long - referenceLong)/sin(long - referenceLong) * expr
           expr = sin lat * cos (long - referenceLong) - tan referenceLat * cos lat
+          y | long - referenceLong == 0 = expr
+            | otherwise = (long - referenceLong) / sin (long - referenceLong) * expr
 
--- | Winkel Tripel projection (standard for the National Geographic Society since
+-- | Winkel Tripel projection
 winkel3 :: Projection
 winkel3 (long, lat) = ((lambda * cos phi1 + (2 * cos lat * sin (lambda/2)/sinc alpha))/2, (lat + sin lat/sinc alpha)/2)
     where lambda = long - lambda0
@@ -41,7 +55,7 @@
     where meridian = radians (-98.5795)
 
 -- | Bonne projection with standard parallel at 45 N and central meridian
--- centered at Washington DC
+-- centered at Washington DC.
 bonne :: Projection
 bonne (long, lat) = (rho * sin e, cot phi1 - rho * cos e)
     where rho = cot phi1 + phi1 - lat
@@ -50,17 +64,18 @@
           meridian = radians (-77.0369) -- central meridian @ dc
           cot = (1/) . tan
 
--- | Albers projection for a given reference point. To make it usable you can
--- use
+-- | Albers projection for a given reference point.
+--
 -- > ablers washingtonDC
 albers :: Point -> Projection
 albers referencePoint (long, lat) = (rho * sin theta, rho' - rho * cos theta)
-    where n = (sin phi1 + sin phi2)/2
+    where n = (sin phi1 + sin phi2) / 2
           theta = n * (long - referenceLong)
           c = cos phi1^(2 :: Int) + 2 * n * sin phi1
           rho = sqrt (c - 2 * n * sin lat) / n
           rho' = sqrt (c - 2 * n * sin referenceLat) / n
-          phi1 = radians 20 -- standard parallels @ 20, 50 degrees
+          -- standard parallels @ 20, 50 degrees
+          phi1 = radians 20
           phi2 = radians 50
           (referenceLong, referenceLat) = referencePoint
 
@@ -70,4 +85,4 @@
 
 -- | Helper to apply a projection given a `Map`.
 projectMap :: Projection -> Map -> Map
-projectMap p = over labelledDistricts (fmap (over _1  (fmap (project p))))
+projectMap p = over labelledDistricts (fmap (first (fmap (project p))))
diff --git a/src/GIS/Math/Spherical.hs b/src/GIS/Math/Spherical.hs
--- a/src/GIS/Math/Spherical.hs
+++ b/src/GIS/Math/Spherical.hs
@@ -1,20 +1,20 @@
 -- | Utilities to compute area, perimeterPolygon, etc. on the surface of a sphere.
-module GIS.Math.Spherical where
+module GIS.Math.Spherical ( areaPolygon
+                          , perimeterPolygon
+                          , relativeCompactness
+                          , totalPerimeter
+                          -- * Spherical geometry
+                          , areaTriangle
+                          , areaConvex
+                          -- * Internal functions
+                          , distance
+                          ) where
 
 import           Control.Composition
-import           Control.Lens
 import           GIS.Math.Projections
 import           GIS.Math.Utils
 import           GIS.Types
 
--- | averages the coördinates of a polygon, returning a point.
-shittyCentroid :: Polygon -> Point
-shittyCentroid poly = (avg $ fmap fst poly, avg $ fmap snd poly)
-
--- | Average over a foldable container
-avg :: (RealFrac a, Foldable t) => t a -> a
-avg list = sum list / (fromIntegral . length $ list)
-
 -- | Compute the area of a triangle using L'Huillier's formula
 areaTriangle :: Point -> Point -> Point -> Double
 areaTriangle x1 x2 x3 = r^(2 :: Int) * e
@@ -29,18 +29,18 @@
 -- TODO mandelbrot/fractal dimension?
 -- consider "area of largest circumscribable circle" as well.
 
--- | Relative compactness, i.e. compactness divided by the compactness of a Euclidean circle
+-- | Relative compactness. Dimensionless.
 relativeCompactness :: Polygon -> Double
 relativeCompactness = (*scale) . compactness1
     where scale = 1/4*pi
 
--- | Take the area of the polygon and divide by the perimeter squared. This is a dimensionless measurement.
+-- | Take the area of the polygon and divide by the perimeter squared. Dimensionless.
 compactness1 :: Polygon -> Double
 compactness1 p = areaPolygon p/perimeterPolygon p^(2 :: Int)
 
 -- | Compute the area of a convex polygon on the surface of a sphere.
 areaConvex :: Polygon -> Double
-areaConvex (base1:base2:pts) = view _1 $ foldr stepArea (0,base2) pts
+areaConvex (base1:base2:pts) = fst $ foldr stepArea (0,base2) pts
     where stepArea point (sum', base) = (sum' + areaTriangle base1 base point, point)
 areaConvex _ = error "attempted to take area of polygon with < 3 points"
 
@@ -50,9 +50,9 @@
 areaPolygon = (*factor) . areaPolyRectangular . fmap (bonne . toRadians)
     where factor = 1717856/4.219690791828533e-2
 
--- | Given a list of polygons, return the total area.
+-- | Given a list of polygons, return the total perimeter.
 totalPerimeter :: [Polygon] -> Double
-totalPerimeter ps = sum $ fmap perimeterPolygon ps
+totalPerimeter = sum . fmap perimeterPolygon
 
 perimeterPolygon :: Polygon -> Double
 perimeterPolygon [x1, x2]       = distance x1 x2
diff --git a/src/GIS/Math/Utils.hs b/src/GIS/Math/Utils.hs
--- a/src/GIS/Math/Utils.hs
+++ b/src/GIS/Math/Utils.hs
@@ -1,9 +1,22 @@
 -- | Miscellaneous utils for math
-module GIS.Math.Utils where
+module GIS.Math.Utils ( radians
+                      , toRadians
+                      , sinc
+                      , avg
+                      , shittyCentroid
+                      ) where
 
-import           Control.Lens
+import           Control.Composition
 import           GIS.Types
 
+-- | Averages the coördinates of a polygon, returning a point.
+shittyCentroid :: Polygon -> Point
+shittyCentroid poly = (avg $ fmap fst poly, avg $ fmap snd poly)
+
+-- | Average over a foldable container
+avg :: (RealFrac a, Foldable t) => t a -> a
+avg list = sum list / (fromIntegral . length $ list)
+
 sinc :: Floating a => a -> a
 sinc x = sin x / x
 
@@ -13,4 +26,4 @@
 
 -- | Convert both coördinates to radians.
 toRadians :: Point -> Point
-toRadians = over _1 radians . over _2 radians
+toRadians = both radians
diff --git a/src/GIS/Types.hs b/src/GIS/Types.hs
--- a/src/GIS/Types.hs
+++ b/src/GIS/Types.hs
@@ -2,7 +2,16 @@
 {-# LANGUAGE TemplateHaskell   #-}
 
 -- | Module containing types for various geometrical objects. Lenses included.
-module GIS.Types where
+module GIS.Types ( -- * Types
+                   Point
+                 , Polygon
+                 , Projection
+                 , District (..)
+                 , DbfReadError (..)
+                 -- * Lenses
+                 , districtLabel
+                 , area
+                 ) where
 
 import           Control.Lens
 import           GHC.Generics
@@ -21,7 +30,7 @@
                          , _compactness   :: Double
                          } deriving (Generic, Show)
 
-makeLenses ''District
+makeLensesFor [("_districtLabel", "districtLabel"), ("_area", "area")] ''District
 
 data DbfReadError = NotAPolygon | ShpNull
 
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,5 +1,5 @@
 ---
-resolver: lts-11.3
+resolver: lts-11.6
 extra-deps:
   - Chart-diagrams-1.8.3
   - composition-prelude-1.3.0.8
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,3 +1,5 @@
+module Main (main) where
+
 import           GIS.Graphics.PlotPNG
 import           GIS.Graphics.PlotSVG
 import           GIS.Hylo
@@ -9,10 +11,10 @@
 main = hspec $ do
     describe "distance" $
         it "computes distances along geodesics" $
-        distance (-74.0059, 40.7128) (-118.2347, 34.0522) `shouldBe` 3934.997673163554
+            distance (-74.0059, 40.7128) (-118.2347, 34.0522) `shouldBe` 3934.997673163554
     describe "mercatorFullPng" $
         it "Reads a map and writes a .png with the mercator projection" $
-        (mkMapPng "test/testmap.png" =<< districtToMapP bonne <$> getDistricts "test/data/worldmap/TM_WORLD_BORDERS-0.3.shp") >>= (`shouldBe` ())
+            (mkMapPng "test/testmap.png" =<< districtToMapP bonne <$> getDistricts "test/data/worldmap/TM_WORLD_BORDERS-0.3.shp") >>= (`shouldBe` ())
     describe "mercatorFullSVG" $
         it "Reads a map and writes a .svg with the mercator projection" $
-        (mkMapSVG "test/testmap.svg" =<< districtToMapP bonne <$> getDistricts "test/data/worldmap/TM_WORLD_BORDERS-0.3.shp") >>= (`shouldBe` ())
+            (mkMapSVG "test/testmap.svg" =<< districtToMapP bonne <$> getDistricts "test/data/worldmap/TM_WORLD_BORDERS-0.3.shp") >>= (`shouldBe` ())
