diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## Cue sheet 2.0.2
+
+* Builds with `mtl-2.3`.
+
 ## Cue sheet 2.0.1
 
 * Got rid of `data-default-class` dependency, which was completely
diff --git a/LICENSE.md b/LICENSE.md
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,4 +1,4 @@
-Copyright © 2016–2018 Mark Karpov
+Copyright © 2016–present Mark Karpov
 
 All rights reserved.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,11 +4,12 @@
 [![Hackage](https://img.shields.io/hackage/v/cue-sheet.svg?style=flat)](https://hackage.haskell.org/package/cue-sheet)
 [![Stackage Nightly](http://stackage.org/package/cue-sheet/badge/nightly)](http://stackage.org/nightly/package/cue-sheet)
 [![Stackage LTS](http://stackage.org/package/cue-sheet/badge/lts)](http://stackage.org/lts/package/cue-sheet)
-[![Build Status](https://travis-ci.org/mrkkrp/cue-sheet.svg?branch=master)](https://travis-ci.org/mrkkrp/cue-sheet)
+![CI](https://github.com/mrkkrp/cue-sheet/workflows/CI/badge.svg?branch=master)
 
-The library allows to construct, render, and parse CUE sheets.
+The library provides support for construction, rendering, and parsing of CUE
+sheets.
 
-## What is CUE sheet?
+## What is a CUE sheet?
 
 > A cue sheet, or cue file, is a metadata file which describes how the
 > tracks of a CD or DVD are laid out. Cue sheets are stored as plain text
@@ -21,23 +22,15 @@
 [here](https://wayback.archive.org/web/20070614044112/http://www.goldenhawk.com/download/cdrwin.pdf),
 scroll to the appendix A (it's closest we get to a “specification”).
 
-## Quick start
-
-[Read the Haddocks](https://hackage.haskell.org/package/cue-sheet). In
-short, you parse a `CueSheet` with `parseCueSheet` function and render a
-`CueSheet` with `renderCueSheet` function—pretty straightforward, eh? Of
-course, you still can construct a `CueSheet` manually. The data types are
-defined in such a way that incorrect CUE sheets are impossible to represent.
-
 ## Contribution
 
 Issues, bugs, and questions may be reported in [the GitHub issue tracker for
 this project](https://github.com/mrkkrp/cue-sheet/issues).
 
-Pull requests are also welcome and will be reviewed quickly.
+Pull requests are also welcome.
 
 ## License
 
-Copyright © 2016–2019 Mark Karpov
+Copyright © 2016–present Mark Karpov
 
 Distributed under BSD 3 clause license.
diff --git a/Text/CueSheet.hs b/Text/CueSheet.hs
--- a/Text/CueSheet.hs
+++ b/Text/CueSheet.hs
@@ -1,44 +1,46 @@
 -- |
 -- Module      :  Text.CueSheet
--- Copyright   :  © 2016–2019 Mark Karpov
+-- Copyright   :  © 2016–present Mark Karpov
 -- License     :  BSD 3 clause
 --
 -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- The module allows to construct, read, and write CUE sheets. The data
--- types are defined in such a way that incorrect CUE sheets are impossible
--- to represent. See 'parseCueSheet' for parsing of plain text CUE sheet
+-- The module allows us to construct, read, and write CUE sheets. The data
+-- types are defined in such a way that incorrect CUE sheets cannot be
+-- represented. See 'parseCueSheet' for parsing of plain text CUE sheet
 -- files and 'renderCueSheet' for rendering.
-
 module Text.CueSheet
   ( -- * Types
-    CueSheet (..)
-  , CueFile (..)
-  , CueFileType (..)
-  , CueTrack (..)
-  , CueTrackType (..)
-  , CueTime (..)
-  , fromMmSsFf
-  , toMmSsFf
-  , showMmSsFf
-  , Mcn
-  , mkMcn
-  , unMcn
-  , CueText
-  , mkCueText
-  , unCueText
-  , Isrc
-  , mkIsrc
-  , unIsrc
-  , CueSheetException (..)
+    CueSheet (..),
+    CueFile (..),
+    CueFileType (..),
+    CueTrack (..),
+    CueTrackType (..),
+    CueTime (..),
+    fromMmSsFf,
+    toMmSsFf,
+    showMmSsFf,
+    Mcn,
+    mkMcn,
+    unMcn,
+    CueText,
+    mkCueText,
+    unCueText,
+    Isrc,
+    mkIsrc,
+    unIsrc,
+    CueSheetException (..),
+
     -- * Parsing
-  , parseCueSheet
-  , CueParserFailure (..)
-  , Eec (..)
+    parseCueSheet,
+    CueParserFailure (..),
+    Eec (..),
+
     -- * Rendering
-  , renderCueSheet )
+    renderCueSheet,
+  )
 where
 
 import Text.CueSheet.Parser
diff --git a/Text/CueSheet/Parser.hs b/Text/CueSheet/Parser.hs
--- a/Text/CueSheet/Parser.hs
+++ b/Text/CueSheet/Parser.hs
@@ -1,6 +1,13 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TypeFamilies #-}
+
 -- |
 -- Module      :  Text.CueSheet.Parser
--- Copyright   :  © 2016–2019 Mark Karpov
+-- Copyright   :  © 2016–present Mark Karpov
 -- License     :  BSD 3 clause
 --
 -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
@@ -9,27 +16,25 @@
 --
 -- The modules contains a CUE sheet parser. You probably want to import
 -- "Text.CueSheet" instead.
-
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric      #-}
-{-# LANGUAGE LambdaCase         #-}
-{-# LANGUAGE OverloadedStrings  #-}
-{-# LANGUAGE RecordWildCards    #-}
-{-# LANGUAGE TypeFamilies       #-}
-
 module Text.CueSheet.Parser
-  ( parseCueSheet
-  , CueParserFailure (..)
-  , Eec (..) )
+  ( parseCueSheet,
+    CueParserFailure (..),
+    Eec (..),
+  )
 where
 
-import Control.Monad.State.Strict
+import Control.Monad (void)
+import Control.Monad.State.Strict (StateT, execStateT, gets, modify)
 import Data.ByteString (ByteString)
 import Data.Data (Data)
 import Data.List.NonEmpty (NonEmpty (..))
+import qualified Data.List.NonEmpty as NE
 import Data.Maybe (isJust)
 import Data.Set (Set)
+import qualified Data.Set as E
 import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
 import Data.Typeable (Typeable)
 import Data.Word (Word8)
 import GHC.Generics
@@ -37,10 +42,6 @@
 import Text.CueSheet.Types
 import Text.Megaparsec
 import Text.Megaparsec.Byte
-import qualified Data.List.NonEmpty         as NE
-import qualified Data.Set                   as E
-import qualified Data.Text                  as T
-import qualified Data.Text.Encoding         as T
 import qualified Text.Megaparsec.Byte.Lexer as L
 
 ----------------------------------------------------------------------------
@@ -48,42 +49,42 @@
 
 -- | Extended error component with support for storing number of track
 -- declaration in which a parsing error has occurred.
-
 data Eec = Eec (Maybe Natural) CueParserFailure
   deriving (Show, Eq, Ord, Data, Typeable, Generic)
 
 instance ShowErrorComponent Eec where
   showErrorComponent (Eec mtrack failure') =
-    showErrorComponent failure' ++ "\n" ++
-    maybe "" (\n -> "in declaration of the track " ++ show n) mtrack
+    showErrorComponent failure'
+      ++ "\n"
+      ++ maybe "" (\n -> "in declaration of the track " ++ show n) mtrack
 
 -- | The enumeration of all failures that may happen during running of
 -- 'parseCueSheet'.
-
 data CueParserFailure
-  = CueParserTrivialError (Maybe (ErrorItem Word8)) (Set (ErrorItem Word8))
-    -- ^ A wrapper for a trivial error
-  | CueParserInvalidCatalog Text
-    -- ^ We ran into an invalid media catalog number
-  | CueParserInvalidCueText Text
-    -- ^ We ran into an invalid text literal
-  | CueParserTrackOutOfOrder
-    -- ^ We spotted a track out of order
-  | CueParserInvalidTrackIsrc Text
-    -- ^ We ran into an invalid ISRC
-  | CueParserInvalidSeconds Natural
-    -- ^ We ran into an invalid number of seconds
-  | CueParserInvalidFrames Natural
-    -- ^ We ran into an invalid number of frames
-  | CueParserTrackIndexOutOfOrder
-    -- ^ We spotted a track index out of order
+  = -- | A wrapper for a trivial error
+    CueParserTrivialError (Maybe (ErrorItem Word8)) (Set (ErrorItem Word8))
+  | -- | We ran into an invalid media catalog number
+    CueParserInvalidCatalog Text
+  | -- | We ran into an invalid text literal
+    CueParserInvalidCueText Text
+  | -- | We spotted a track out of order
+    CueParserTrackOutOfOrder
+  | -- | We ran into an invalid ISRC
+    CueParserInvalidTrackIsrc Text
+  | -- | We ran into an invalid number of seconds
+    CueParserInvalidSeconds Natural
+  | -- | We ran into an invalid number of frames
+    CueParserInvalidFrames Natural
+  | -- | We spotted a track index out of order
+    CueParserTrackIndexOutOfOrder
   deriving (Show, Eq, Ord, Data, Typeable, Generic)
 
 instance ShowErrorComponent CueParserFailure where
   showErrorComponent = \case
     CueParserTrivialError us es ->
-      init $ parseErrorTextPretty
-        (TrivialError undefined us es :: ParseError ByteString Eec)
+      init $
+        parseErrorTextPretty
+          (TrivialError undefined us es :: ParseError ByteString Eec)
     CueParserInvalidCatalog txt ->
       "the value \"" ++ T.unpack txt ++ "\" is not a valid Media Catalog Number"
     CueParserInvalidCueText txt ->
@@ -100,129 +101,159 @@
       "this index appears out of order"
 
 -- | Type of parser we use here, it's not public.
-
 type Parser a = StateT Context (Parsec Eec ByteString) a
 
 -- | Context of parsing. This is passed around in 'StateT'. We need all of
 -- this to signal parse errors on duplicate declarations of things that
 -- should only be declared once according to description of the format, to
 -- validate track numbers, etc.
-
 data Context = Context
-  { contextCueSheet   :: !CueSheet
-    -- ^ Current state of CUE sheet we parse. When a part\/parameter of CUE
+  { -- | Current state of CUE sheet we parse. When a part\/parameter of CUE
     -- sheet is parsed, this thing is updated.
-  , contextFiles      :: ![CueFile]
-    -- ^ Temporary storage for parsed files (we can't store it in the
+    contextCueSheet :: !CueSheet,
+    -- | Temporary storage for parsed files (we can't store it in the
     -- 'CueSheet' because it does not allow empty list of files).
-  , contextTracks     :: ![CueTrack]
-    -- ^ Similar to 'contextFiles', collection of tracks but for current
+    contextFiles :: ![CueFile],
+    -- | Similar to 'contextFiles', collection of tracks but for current
     -- file.
-  , contextTrackCount :: !Natural
-    -- ^ Number of tracks we have parsed so far, to avoid traversing lists
+    contextTracks :: ![CueTrack],
+    -- | Number of tracks we have parsed so far, to avoid traversing lists
     -- again and again.
-  , contextIndices    :: ![CueTime]
-    -- ^ Temporary storage for collection indices for current track.
-  , contextIndexCount :: !Natural
-    -- ^ Similarly for indices.
+    contextTrackCount :: !Natural,
+    -- | Temporary storage for collection indices for current track.
+    contextIndices :: ![CueTime],
+    -- | Similarly for indices.
+    contextIndexCount :: !Natural
   }
 
 -- | Parse a CUE sheet from a lazy 'BL.ByteString'.
-
-parseCueSheet
-  :: String            -- ^ File name to include in error messages
-  -> ByteString     -- ^ CUE sheet to parse as a lazy 'BL.ByteString'
-  -> Either (ParseErrorBundle ByteString Eec) CueSheet -- ^ 'ParseError' or result
+parseCueSheet ::
+  -- | File name to include in error messages
+  String ->
+  -- | CUE sheet to parse as a lazy 'BL.ByteString'
+  ByteString ->
+  -- | 'ParseError' or result
+  Either (ParseErrorBundle ByteString Eec) CueSheet
 parseCueSheet = parse (contextCueSheet <$> execStateT pCueSheet initContext)
   where
-    initContext = Context
-      { contextCueSheet = CueSheet
-        { cueCatalog          = Nothing
-        , cueCdTextFile       = Nothing
-        , cuePerformer        = Nothing
-        , cueTitle            = Nothing
-        , cueSongwriter       = Nothing
-        , cueFirstTrackNumber = 0
-        , cueFiles            = dummyFile :| [] }
-      , contextFiles          = []
-      , contextTracks         = []
-      , contextTrackCount     = 0
-      , contextIndices        = []
-      , contextIndexCount     = 0 }
+    initContext =
+      Context
+        { contextCueSheet =
+            CueSheet
+              { cueCatalog = Nothing,
+                cueCdTextFile = Nothing,
+                cuePerformer = Nothing,
+                cueTitle = Nothing,
+                cueSongwriter = Nothing,
+                cueFirstTrackNumber = 0,
+                cueFiles = dummyFile :| []
+              },
+          contextFiles = [],
+          contextTracks = [],
+          contextTrackCount = 0,
+          contextIndices = [],
+          contextIndexCount = 0
+        }
 
 -- | Parse a 'CueSheet'. The result is not returned, but written in the
 -- 'Context'.
-
 pCueSheet :: Parser ()
 pCueSheet = do
   scn
   void (many pHeaderItem)
   void (some pFile)
   -- NOTE Lens would help here, but let's keep this vanilla.
-  modify $ \x -> x { contextCueSheet =
-    (contextCueSheet x)
-      { cueFiles = (NE.fromList . reverse . contextFiles) x } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x)
+            { cueFiles = (NE.fromList . reverse . contextFiles) x
+            }
+      }
   eof
 
 pHeaderItem :: Parser ()
-pHeaderItem = choice
-  [ pCatalog
-  , pCdTextFile
-  , pPerformer
-  , pTitle
-  , pSongwriter
-  , pRem ]
+pHeaderItem =
+  choice
+    [ pCatalog,
+      pCdTextFile,
+      pPerformer,
+      pTitle,
+      pSongwriter,
+      pRem
+    ]
 
 pCatalog :: Parser ()
 pCatalog = do
   already <- gets (isJust . cueCatalog . contextCueSheet)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkMcn x of
-          Nothing -> Left (CueParserInvalidCatalog x)
-          Just mcn -> Right mcn
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkMcn x of
+              Nothing -> Left (CueParserInvalidCatalog x)
+              Just mcn -> Right mcn
   mcn <- labelledLit already f "CATALOG"
-  modify $ \x -> x { contextCueSheet =
-    (contextCueSheet x) { cueCatalog = Just mcn } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x) {cueCatalog = Just mcn}
+      }
 
 pCdTextFile :: Parser ()
 pCdTextFile = do
   already <- gets (isJust . cueCdTextFile . contextCueSheet)
   cdTextFile <- T.decodeUtf8 <$> labelledLit already Right "CDTEXTFILE"
-  modify $ \x -> x { contextCueSheet = (contextCueSheet x)
-    { cueCdTextFile = Just (T.unpack cdTextFile) } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x)
+            { cueCdTextFile = Just (T.unpack cdTextFile)
+            }
+      }
 
 pPerformer :: Parser ()
 pPerformer = do
   already <- gets (isJust . cuePerformer . contextCueSheet)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   performer <- labelledLit already f "PERFORMER"
-  modify $ \x -> x { contextCueSheet =
-    (contextCueSheet x) { cuePerformer = Just performer } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x) {cuePerformer = Just performer}
+      }
 
 pTitle :: Parser ()
 pTitle = do
   already <- gets (isJust . cueTitle . contextCueSheet)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   title <- labelledLit already f "TITLE"
-  modify $ \x -> x { contextCueSheet =
-    (contextCueSheet x) { cueTitle = Just title } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x) {cueTitle = Just title}
+      }
 
 pSongwriter :: Parser ()
 pSongwriter = do
   already <- gets (isJust . cueSongwriter . contextCueSheet)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   songwriter <- labelledLit already f "SONGWRITER"
-  modify $ \x -> x { contextCueSheet =
-    (contextCueSheet x) { cueSongwriter = Just songwriter } }
+  modify $ \x ->
+    x
+      { contextCueSheet =
+          (contextCueSheet x) {cueSongwriter = Just songwriter}
+      }
 
 pRem :: Parser ()
 pRem = do
@@ -233,82 +264,103 @@
 pFile = do
   void (symbol "FILE")
   filename <- T.decodeUtf8 <$> lexeme stringLit
-  let pFiletype = choice
-        [ Binary   <$ symbol "BINARY"
-        , Motorola <$ symbol "MOTOROLA"
-        , Aiff     <$ symbol "AIFF"
-        , Wave     <$ symbol "WAVE"
-        , MP3      <$ symbol "MP3" ]
+  let pFiletype =
+        choice
+          [ Binary <$ symbol "BINARY",
+            Motorola <$ symbol "MOTOROLA",
+            Aiff <$ symbol "AIFF",
+            Wave <$ symbol "WAVE",
+            MP3 <$ symbol "MP3"
+          ]
   filetype <- pFiletype <* eol <* scn
   void (some (pTrack <|> pRem))
   tracks <- gets contextTracks
-  let newFile = CueFile
-        { cueFileName   = T.unpack filename
-        , cueFileType   = filetype
-        , cueFileTracks = NE.fromList (reverse tracks) }
-  modify $ \x -> x
-    { contextFiles  = newFile : contextFiles x
-    , contextTracks = [] }
+  let newFile =
+        CueFile
+          { cueFileName = T.unpack filename,
+            cueFileType = filetype,
+            cueFileTracks = NE.fromList (reverse tracks)
+          }
+  modify $ \x ->
+    x
+      { contextFiles = newFile : contextFiles x,
+        contextTracks = []
+      }
 
 pTrack :: Parser ()
 pTrack = do
   void (symbol "TRACK")
   trackOffset <- gets (cueFirstTrackNumber . contextCueSheet)
-  trackCount  <- gets contextTrackCount
+  trackCount <- gets contextTrackCount
   let firstTrack = trackCount == 0
       f x =
         if firstTrack || x == trackOffset + trackCount
           then Right x
           else Left CueParserTrackOutOfOrder
   n <- withCheck f (lexeme L.decimal)
-  let pTrackType = choice
-        [ CueTrackAudio      <$ symbol "AUDIO"
-        , CueTrackCdg        <$ symbol "CDG"
-        , CueTrackMode1_2048 <$ symbol "MODE1/2048"
-        , CueTrackMode1_2352 <$ symbol "MODE1/2352"
-        , CueTrackMode2_2336 <$ symbol "MODE2/2336"
-        , CueTrackMode2_2352 <$ symbol "MODE2/2352"
-        , CueTrackCdi2336    <$ symbol "CDI/2336"
-        , CueTrackCdi2352    <$ symbol "CDI/2352" ]
+  let pTrackType =
+        choice
+          [ CueTrackAudio <$ symbol "AUDIO",
+            CueTrackCdg <$ symbol "CDG",
+            CueTrackMode1_2048 <$ symbol "MODE1/2048",
+            CueTrackMode1_2352 <$ symbol "MODE1/2352",
+            CueTrackMode2_2336 <$ symbol "MODE2/2336",
+            CueTrackMode2_2352 <$ symbol "MODE2/2352",
+            CueTrackCdi2336 <$ symbol "CDI/2336",
+            CueTrackCdi2352 <$ symbol "CDI/2352"
+          ]
   trackType <- pTrackType <* eol <* scn
-  let newTrack = dummyTrack { cueTrackType = trackType }
-  modify $ \x -> x
-    { contextTracks     = newTrack : contextTracks x
-    , contextTrackCount = trackCount + 1
-    , contextCueSheet   = let old = contextCueSheet x in
-        if firstTrack
-          then old { cueFirstTrackNumber = n }
-          else old }
+  let newTrack = dummyTrack {cueTrackType = trackType}
+  modify $ \x ->
+    x
+      { contextTracks = newTrack : contextTracks x,
+        contextTrackCount = trackCount + 1,
+        contextCueSheet =
+          let old = contextCueSheet x
+           in if firstTrack
+                then old {cueFirstTrackNumber = n}
+                else old
+      }
   inTrack n $ do
     void (many pTrackHeaderItem)
     index0 <- (optional . try . pIndex) 0
-    modify $ \x -> x
-      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-          t { cueTrackPregapIndex = index0 } }
-    modify $ \x -> x
-      { contextIndices    = []
-      , contextIndexCount = 0 }
+    modify $ \x ->
+      x
+        { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+            t {cueTrackPregapIndex = index0}
+        }
+    modify $ \x ->
+      x
+        { contextIndices = [],
+          contextIndexCount = 0
+        }
     let grabIndex = do
           next <- (+ 1) <$> gets contextIndexCount
           nextIndex <- pIndex next
-          modify $ \x -> x
-            { contextIndices    = nextIndex : contextIndices x
-            , contextIndexCount = next }
+          modify $ \x ->
+            x
+              { contextIndices = nextIndex : contextIndices x,
+                contextIndexCount = next
+              }
     void (some (grabIndex <|> pRem))
-    modify $ \x -> x
-      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-          t { cueTrackIndices = (NE.fromList . reverse . contextIndices) x } }
+    modify $ \x ->
+      x
+        { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+            t {cueTrackIndices = (NE.fromList . reverse . contextIndices) x}
+        }
     void (optional pPostgap)
 
 pTrackHeaderItem :: Parser ()
-pTrackHeaderItem = choice
-  [ pFlags
-  , pIsrc
-  , pTrackPerformer
-  , pTrackTitle
-  , pTrackSongwriter
-  , pRem
-  , pPregap ]
+pTrackHeaderItem =
+  choice
+    [ pFlags,
+      pIsrc,
+      pTrackPerformer,
+      pTrackTitle,
+      pTrackSongwriter,
+      pRem,
+      pPregap
+    ]
 
 pFlags :: Parser ()
 pFlags = do
@@ -317,89 +369,108 @@
   void (some pFlag) <* eol <* scn
 
 -- | A helper data type for track flags.
-
 data CueTrackFlag = DCP | FourCH | PRE | SCMS
 
 pFlag :: Parser ()
 pFlag = do
-  flag <- choice
-    [ DCP    <$ symbol "DCP"
-    , FourCH <$ symbol "4CH"
-    , PRE    <$ symbol "PRE"
-    , SCMS   <$ symbol "SCMS" ]
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        case flag of
-          DCP    -> t { cueTrackDigitalCopyPermitted = True }
-          FourCH -> t { cueTrackFourChannelAudio     = True }
-          PRE    -> t { cueTrackPreemphasisEnabled   = True }
-          SCMS   -> t { cueTrackSerialCopyManagement = True } }
+  flag <-
+    choice
+      [ DCP <$ symbol "DCP",
+        FourCH <$ symbol "4CH",
+        PRE <$ symbol "PRE",
+        SCMS <$ symbol "SCMS"
+      ]
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          case flag of
+            DCP -> t {cueTrackDigitalCopyPermitted = True}
+            FourCH -> t {cueTrackFourChannelAudio = True}
+            PRE -> t {cueTrackPreemphasisEnabled = True}
+            SCMS -> t {cueTrackSerialCopyManagement = True}
+      }
 
 pIsrc :: Parser ()
 pIsrc = do
   already <- gets (isJust . cueTrackIsrc . head . contextTracks)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkIsrc x of
-          Nothing -> Left (CueParserInvalidTrackIsrc x)
-          Just isrc -> Right isrc
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkIsrc x of
+              Nothing -> Left (CueParserInvalidTrackIsrc x)
+              Just isrc -> Right isrc
   isrc <- labelledLit already f "ISRC"
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackIsrc = Just isrc } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackIsrc = Just isrc}
+      }
 
 pTrackPerformer :: Parser ()
 pTrackPerformer = do
   already <- gets (isJust . cueTrackPerformer . head . contextTracks)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   performer <- labelledLit already f "PERFORMER"
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackPerformer = Just performer } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackPerformer = Just performer}
+      }
 
 pTrackTitle :: Parser ()
 pTrackTitle = do
   already <- gets (isJust . cueTrackTitle . head . contextTracks)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   title <- labelledLit already f "TITLE"
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackTitle = Just title } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackTitle = Just title}
+      }
 
 pTrackSongwriter :: Parser ()
 pTrackSongwriter = do
   already <- gets (isJust . cueTrackSongwriter . head . contextTracks)
-  let f x' = let x = T.decodeUtf8 x' in
-        case mkCueText x of
-          Nothing -> Left (CueParserInvalidCueText x)
-          Just txt -> Right txt
+  let f x' =
+        let x = T.decodeUtf8 x'
+         in case mkCueText x of
+              Nothing -> Left (CueParserInvalidCueText x)
+              Just txt -> Right txt
   songwriter <- labelledLit already f "SONGWRITER"
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackSongwriter = Just songwriter } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackSongwriter = Just songwriter}
+      }
 
 pPregap :: Parser ()
 pPregap = do
   already <- gets (isJust . cueTrackPregap . head . contextTracks)
   failAtIf already "PREGAP"
   time <- lexeme cueTime <* eol <* scn
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackPregap = Just time } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackPregap = Just time}
+      }
 
 pPostgap :: Parser ()
 pPostgap = do
   already <- gets (isJust . cueTrackPostgap . head . contextTracks)
   failAtIf already "POSTGAP"
   time <- lexeme cueTime <* eol <* scn
-  modify $ \x -> x
-    { contextTracks = changingFirstOf (contextTracks x) $ \t ->
-        t { cueTrackPostgap = Just time } }
+  modify $ \x ->
+    x
+      { contextTracks = changingFirstOf (contextTracks x) $ \t ->
+          t {cueTrackPostgap = Just time}
+      }
 
 pIndex :: Natural -> Parser CueTime
 pIndex n = do
@@ -425,20 +496,17 @@
           else Left (CueParserInvalidFrames n)
   seconds <- withCheck checkSeconds naturalLit
   void (char 58)
-  frames  <- withCheck checkFrames  naturalLit
+  frames <- withCheck checkFrames naturalLit
   case fromMmSsFf minutes seconds frames of
     Nothing -> empty -- NOTE must be always valid, we checked already
-    Just  x -> return x
+    Just x -> return x
 
 ----------------------------------------------------------------------------
 -- Helpers
 
--- | Parse a thing and then check if it's OK conceptually. If it's not OK,
--- the error will be reported with position at the start of offending
--- lexeme, otherwise the lexeme is parsed as usual. Of course if the lexeme
--- has incorrect format, that is just reported and no additional check
--- happens.
-
+-- | Parse something and then check if it's OK. If it's not OK, the error
+-- will be reported with position at the start of the offending lexeme,
+-- otherwise the lexeme is parsed as usual.
 withCheck :: (a -> Either CueParserFailure b) -> Parser a -> Parser b
 withCheck check p = do
   o <- getOffset
@@ -452,7 +520,6 @@
 -- | If the first argument is 'True' and we can parse the given command,
 -- fail pointing at the beginning of the command and report it as something
 -- unexpected.
-
 failAtIf :: Bool -> ByteString -> Parser ()
 failAtIf shouldFail command = do
   let p = void (symbol command)
@@ -464,106 +531,105 @@
 -- | Indicate that the inner parser belongs to declaration of a track with
 -- the given index. The index of the track will be added to 'ParseError's to
 -- help the user find where the error happened.
-
 inTrack :: Natural -> Parser a -> Parser a
 inTrack n = region f
   where
-    f (TrivialError pos us es) = FancyError pos . E.singleton $
-      ErrorCustom (Eec (Just n) (CueParserTrivialError us es))
+    f (TrivialError pos us es) =
+      FancyError pos . E.singleton $
+        ErrorCustom (Eec (Just n) (CueParserTrivialError us es))
     f (FancyError pos xs) = FancyError pos (E.map g xs)
     g (ErrorCustom (Eec mn x)) = ErrorCustom (Eec (mn <|> Just n) x)
     g e = e
 
 -- | A labelled literal (a helper for common case).
-
-labelledLit
-  :: Bool              -- ^ Should we instantly fail when command is parsed?
-  -> (ByteString -> Either CueParserFailure a) -- ^ How to judge the result
-  -> ByteString        -- ^ Name of the command to grab
-  -> Parser a
+labelledLit ::
+  -- | Should we instantly fail when command is parsed?
+  Bool ->
+  -- | How to judge the result
+  (ByteString -> Either CueParserFailure a) ->
+  -- | Name of the command to grab
+  ByteString ->
+  Parser a
 labelledLit shouldFail check command = do
   failAtIf shouldFail command
   withCheck check (lexeme stringLit) <* eol <* scn
 
 -- | String literal with support for quotation.
-
 stringLit :: Parser ByteString
-stringLit = (quoted <?> "quoted string literal")
-  <|> (unquoted <?> "unquoted string literal")
+stringLit =
+  (quoted <?> "quoted string literal")
+    <|> (unquoted <?> "unquoted string literal")
   where
-    quoted   = char 34 *> takeWhileP Nothing f <* char 34
+    quoted = char 34 *> takeWhileP Nothing f <* char 34
     unquoted = takeWhileP Nothing g
-    f x      = x /= 10 && x /= 34
-    g x      = x /= 10 && x /= 9 && x /= 13 && x /= 32
+    f x = x /= 10 && x /= 34
+    g x = x /= 10 && x /= 9 && x /= 13 && x /= 32
 
 -- | Parse a 'Natural'.
-
 naturalLit :: Parser Natural
 naturalLit = L.decimal
 
 -- | Case-insensitive symbol parser.
-
 symbol :: ByteString -> Parser ByteString
 symbol s = string' s <* notFollowedBy alphaNumChar <* sc
 
 -- | A wrapper for lexemes.
-
 lexeme :: Parser a -> Parser a
 lexeme = L.lexeme sc
 
 -- | Space consumer (eats newlines).
-
 scn :: Parser ()
 scn = L.space space1 empty empty
 
 -- | Space consumer (does not eat newlines).
-
 sc :: Parser ()
 sc = L.space (void $ takeWhile1P Nothing f) empty empty
   where
     f x = x == 32 || x == 9
 
 -- | Determine by 'CueTrack' if we have already parsed FLAGS command.
-
 seenFlags :: CueTrack -> Bool
-seenFlags CueTrack {..} = or
-  [ cueTrackDigitalCopyPermitted
-  , cueTrackFourChannelAudio
-  , cueTrackPreemphasisEnabled
-  , cueTrackSerialCopyManagement ]
+seenFlags CueTrack {..} =
+  or
+    [ cueTrackDigitalCopyPermitted,
+      cueTrackFourChannelAudio,
+      cueTrackPreemphasisEnabled,
+      cueTrackSerialCopyManagement
+    ]
 
 -- | Apply given function to the first element of the list.
-
 changingFirstOf :: [a] -> (a -> a) -> [a]
 changingFirstOf [] _ = []
-changingFirstOf (x:xs) f = f x : xs
+changingFirstOf (x : xs) f = f x : xs
 
 ----------------------------------------------------------------------------
 -- Dummies
 
 -- | A dummy file. It's only here because 'CueSheet' can't have an empty
 -- list of files and it cannot be a bottom either.
-
 dummyFile :: CueFile
-dummyFile = CueFile
-  { cueFileName   = ""
-  , cueFileType   = Wave
-  , cueFileTracks = dummyTrack :| [] }
+dummyFile =
+  CueFile
+    { cueFileName = "",
+      cueFileType = Wave,
+      cueFileTracks = dummyTrack :| []
+    }
 
 -- | A dummy track, see 'dummyFile'.
-
 dummyTrack :: CueTrack
-dummyTrack = CueTrack
-  { cueTrackDigitalCopyPermitted = False
-  , cueTrackFourChannelAudio     = False
-  , cueTrackPreemphasisEnabled   = False
-  , cueTrackSerialCopyManagement = False
-  , cueTrackType                 = CueTrackAudio
-  , cueTrackIsrc                 = Nothing
-  , cueTrackTitle                = Nothing
-  , cueTrackPerformer            = Nothing
-  , cueTrackSongwriter           = Nothing
-  , cueTrackPregap               = Nothing
-  , cueTrackPregapIndex          = Nothing
-  , cueTrackIndices              = CueTime 0 :| []
-  , cueTrackPostgap              = Nothing }
+dummyTrack =
+  CueTrack
+    { cueTrackDigitalCopyPermitted = False,
+      cueTrackFourChannelAudio = False,
+      cueTrackPreemphasisEnabled = False,
+      cueTrackSerialCopyManagement = False,
+      cueTrackType = CueTrackAudio,
+      cueTrackIsrc = Nothing,
+      cueTrackTitle = Nothing,
+      cueTrackPerformer = Nothing,
+      cueTrackSongwriter = Nothing,
+      cueTrackPregap = Nothing,
+      cueTrackPregapIndex = Nothing,
+      cueTrackIndices = CueTime 0 :| [],
+      cueTrackPostgap = Nothing
+    }
diff --git a/Text/CueSheet/Render.hs b/Text/CueSheet/Render.hs
--- a/Text/CueSheet/Render.hs
+++ b/Text/CueSheet/Render.hs
@@ -1,6 +1,10 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+
 -- |
 -- Module      :  Text.CueSheet.Render
--- Copyright   :  © 2016–2019 Mark Karpov
+-- Copyright   :  © 2016–present Mark Karpov
 -- License     :  BSD 3 clause
 --
 -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
@@ -9,47 +13,45 @@
 --
 -- The module contains a CUE sheet render. You probably want to import
 -- "Text.CueSheet" instead.
-
-{-# LANGUAGE FlexibleContexts  #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards   #-}
-
 module Text.CueSheet.Render
-  ( renderCueSheet )
+  ( renderCueSheet,
+  )
 where
 
 import Control.Monad
 import Control.Monad.State
 import Control.Monad.Writer.Lazy
-import Data.Char (isSpace, chr)
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Builder as BB
+import qualified Data.ByteString.Lazy as BL
+import Data.Char (chr, isSpace)
+import qualified Data.List.NonEmpty as NE
 import Data.Maybe (catMaybes)
 import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
 import Numeric.Natural
 import Text.CueSheet.Types
 import Text.Printf (printf)
-import qualified Data.ByteString         as B
-import qualified Data.ByteString.Builder as BB
-import qualified Data.ByteString.Lazy    as BL
-import qualified Data.List.NonEmpty      as NE
-import qualified Data.Text               as T
-import qualified Data.Text.Encoding      as T
 
 -- | Render a CUE sheet as a lazy 'BL.ByteString'. All 'Text' values in the
 -- 'CueSheet' will be UTF-8 encoded.
-
-renderCueSheet
-  :: Bool              -- ^ Use CRLF sequence as “end of line” separator
-  -> CueSheet          -- ^ The 'CueSheet' to render
-  -> BL.ByteString     -- ^ The result
+renderCueSheet ::
+  -- | Use CRLF sequence as “end of line” separator
+  Bool ->
+  -- | The 'CueSheet' to render
+  CueSheet ->
+  -- | The result
+  BL.ByteString
 renderCueSheet csrf CueSheet {..} =
   BB.toLazyByteString . execWriter . flip evalStateT (max cueFirstTrackNumber 1) $ do
-    let eol        = tell (if csrf then "\r\n" else "\n")
+    let eol = tell (if csrf then "\r\n" else "\n")
         tellText x =
           let raw = T.encodeUtf8 x
-          in tell . BB.byteString $
-             if B.any (isSpace . chr . fromIntegral) raw || B.null raw
-               then "\"" <> raw <> "\""
-               else raw
+           in tell . BB.byteString $
+                if B.any (isSpace . chr . fromIntegral) raw || B.null raw
+                  then "\"" <> raw <> "\""
+                  else raw
     forM_ cueCatalog $ \x -> do
       tell "CATALOG "
       tellText (unMcn x)
@@ -84,11 +86,13 @@
         tell " "
         tellText (renderTrackType cueTrackType)
         eol
-        let flags = catMaybes
-              [ if cueTrackDigitalCopyPermitted then Just "DCP"  else Nothing
-              , if cueTrackFourChannelAudio     then Just "4CH"  else Nothing
-              , if cueTrackPreemphasisEnabled   then Just "PRE"  else Nothing
-              , if cueTrackSerialCopyManagement then Just "SCMS" else Nothing ]
+        let flags =
+              catMaybes
+                [ if cueTrackDigitalCopyPermitted then Just "DCP" else Nothing,
+                  if cueTrackFourChannelAudio then Just "4CH" else Nothing,
+                  if cueTrackPreemphasisEnabled then Just "PRE" else Nothing,
+                  if cueTrackSerialCopyManagement then Just "SCMS" else Nothing
+                ]
         unless (null flags) $ do
           tell "    FLAGS "
           (tell . BB.byteString) (B.intercalate " " flags)
@@ -117,7 +121,7 @@
           tell "    INDEX 00 "
           tellText (showMmSsFf x)
           eol
-        forM_ (NE.zip (NE.fromList [1..]) cueTrackIndices) $ \(n, index) -> do
+        forM_ (NE.zip (NE.fromList [1 ..]) cueTrackIndices) $ \(n, index) -> do
           tell "    INDEX "
           tellText (formatNat n)
           tell " "
@@ -132,27 +136,24 @@
 -- Helpers
 
 -- | Format a 'Natural' padding it with zeros to 2 digits.
-
 formatNat :: Natural -> Text
 formatNat = T.pack . printf "%02d"
 
 -- | Render a 'CueFileType' as per the CUE specs.
-
 renderFileType :: CueFileType -> Text
-renderFileType Binary   = "BINARY"
+renderFileType Binary = "BINARY"
 renderFileType Motorola = "MOTOROLA"
-renderFileType Aiff     = "AIFF"
-renderFileType Wave     = "WAVE"
-renderFileType MP3      = "MP3"
+renderFileType Aiff = "AIFF"
+renderFileType Wave = "WAVE"
+renderFileType MP3 = "MP3"
 
 -- | Render a 'CueTrackType' as per the CUE specs.
-
 renderTrackType :: CueTrackType -> Text
-renderTrackType CueTrackAudio      = "AUDIO"
-renderTrackType CueTrackCdg        = "CDG"
+renderTrackType CueTrackAudio = "AUDIO"
+renderTrackType CueTrackCdg = "CDG"
 renderTrackType CueTrackMode1_2048 = "MODE1/2048"
 renderTrackType CueTrackMode1_2352 = "MODE1/2352"
 renderTrackType CueTrackMode2_2336 = "MODE2/2336"
 renderTrackType CueTrackMode2_2352 = "MODE2/2352"
-renderTrackType CueTrackCdi2336    = "CDI/2336"
-renderTrackType CueTrackCdi2352    = "CDI/2352"
+renderTrackType CueTrackCdi2336 = "CDI/2336"
+renderTrackType CueTrackCdi2352 = "CDI/2352"
diff --git a/Text/CueSheet/Types.hs b/Text/CueSheet/Types.hs
--- a/Text/CueSheet/Types.hs
+++ b/Text/CueSheet/Types.hs
@@ -1,6 +1,8 @@
+{-# LANGUAGE DeriveGeneric #-}
+
 -- |
 -- Module      :  Text.CueSheet.Types
--- Copyright   :  © 2016–2019 Mark Karpov
+-- Copyright   :  © 2016–present Mark Karpov
 -- License     :  BSD 3 clause
 --
 -- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
@@ -9,181 +11,185 @@
 --
 -- Types describing structure of a CUE sheet. You probably want to import
 -- "Text.CueSheet" instead.
-
-{-# LANGUAGE CPP           #-}
-{-# LANGUAGE DeriveGeneric #-}
-
 module Text.CueSheet.Types
-  ( CueSheet (..)
-  , CueFile (..)
-  , CueFileType (..)
-  , CueTrack (..)
-  , CueTrackType (..)
-  , CueTime (..)
-  , fromMmSsFf
-  , toMmSsFf
-  , showMmSsFf
-  , Mcn
-  , mkMcn
-  , unMcn
-  , CueText
-  , mkCueText
-  , unCueText
-  , Isrc
-  , mkIsrc
-  , unIsrc
-  , CueSheetException (..) )
+  ( CueSheet (..),
+    CueFile (..),
+    CueFileType (..),
+    CueTrack (..),
+    CueTrackType (..),
+    CueTime (..),
+    fromMmSsFf,
+    toMmSsFf,
+    showMmSsFf,
+    Mcn,
+    mkMcn,
+    unMcn,
+    CueText,
+    mkCueText,
+    unCueText,
+    Isrc,
+    mkIsrc,
+    unIsrc,
+    CueSheetException (..),
+  )
 where
 
 import Control.Monad.Catch
-import Data.Char (isDigit, isAscii, isLetter)
+import Data.Char (isAscii, isDigit, isLetter)
 import Data.List.NonEmpty (NonEmpty (..))
-import Data.Monoid ((<>))
+import qualified Data.List.NonEmpty as NE
 import Data.Text (Text)
+import qualified Data.Text as T
 import GHC.Generics
 import Numeric.Natural
 import Test.QuickCheck
 import Text.Printf (printf)
-import qualified Data.List.NonEmpty as NE
-import qualified Data.Text          as T
 
--- | Entire CUE sheet, contains one or more files (see 'CueFile').
-
+-- | CUE sheet, contains one or more files (see 'CueFile').
 data CueSheet = CueSheet
-  { cueCatalog    :: !(Maybe Mcn)
-    -- ^ Disc's Media Catalog Number (see 'Mcn').
-  , cueCdTextFile :: !(Maybe FilePath)
-    -- ^ Name of the file that contains the encoded CD-Text information for
+  { -- | Disc's Media Catalog Number (see 'Mcn').
+    cueCatalog :: !(Maybe Mcn),
+    -- | Name of the file that contains the encoded CD-Text information for
     -- the disc.
-  , cuePerformer  :: !(Maybe CueText)
-    -- ^ Performer of the entire disc.
-  , cueTitle      :: !(Maybe CueText)
-    -- ^ Title of the entire disc.
-  , cueSongwriter :: !(Maybe CueText)
-    -- ^ Songwriter of the entire disc.
-  , cueFirstTrackNumber :: !Natural
-    -- ^ Number of the first track. Typically 1, but may be greater than 1.
-  , cueFiles      :: !(NonEmpty CueFile)
-    -- ^ Collection of files to be written.
-  } deriving (Show, Eq, Ord, Generic)
+    cueCdTextFile :: !(Maybe FilePath),
+    -- | Performer of the entire disc.
+    cuePerformer :: !(Maybe CueText),
+    -- | Title of the entire disc.
+    cueTitle :: !(Maybe CueText),
+    -- | Songwriter of the entire disc.
+    cueSongwriter :: !(Maybe CueText),
+    -- | Number of the first track. Typically 1, but may be greater than 1.
+    cueFirstTrackNumber :: !Natural,
+    -- | Collection of files to be written.
+    cueFiles :: !(NonEmpty CueFile)
+  }
+  deriving (Show, Eq, Ord, Generic)
 
 instance Arbitrary CueSheet where
-  arbitrary = CueSheet
-    <$> arbitrary
-    <*> oneof [pure Nothing, Just <$> filepath]
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> (fromInteger . getPositive <$> arbitrary)
-    <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
+  arbitrary =
+    CueSheet
+      <$> arbitrary
+      <*> oneof [pure Nothing, Just <$> filepath]
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> (fromInteger . getPositive <$> arbitrary)
+      <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
 
 -- | A file to be written. Single file can be divided into one or more
 -- tracks (see 'CueTrack').
-
 data CueFile = CueFile
-  { cueFileName   :: !FilePath
-    -- ^ Name of file.
-  , cueFileType   :: !CueFileType
-    -- ^ Type of file.
-  , cueFileTracks :: !(NonEmpty CueTrack)
-    -- ^ Collection of tracks in the file.
-  } deriving (Show, Eq, Ord, Generic)
+  { -- | Name of file.
+    cueFileName :: !FilePath,
+    -- | Type of file.
+    cueFileType :: !CueFileType,
+    -- | Collection of tracks in the file.
+    cueFileTracks :: !(NonEmpty CueTrack)
+  }
+  deriving (Show, Eq, Ord, Generic)
 
 instance Arbitrary CueFile where
-  arbitrary = CueFile
-    <$> filepath
-    <*> arbitrary
-    <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
+  arbitrary =
+    CueFile
+      <$> filepath
+      <*> arbitrary
+      <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
 
 -- | Enumeration of audio or file's data types.
-
 data CueFileType
-  = Binary
-    -- ^ Intel binary file (least significant byte first). Use for data
+  = -- | Intel binary file (least significant byte first). Use for data
     -- files.
-  | Motorola
-    -- ^ Motorola binary file (most significant file first). Use for data
+    Binary
+  | -- | Motorola binary file (most significant file first). Use for data
     -- files.
-  | Aiff
-    -- ^ Audio AIFF file (44.1 kHz, 16 bit stereo).
-  | Wave
-    -- ^ Audio WAVE file (44.1 kHz, 16 bit stereo).
-  | MP3
-    -- ^ Audio MP3 file (44.1 kHz 16 bit stereo).
+    Motorola
+  | -- | Audio AIFF file (44.1 kHz, 16 bit stereo).
+    Aiff
+  | -- | Audio WAVE file (44.1 kHz, 16 bit stereo).
+    Wave
+  | -- | Audio MP3 file (44.1 kHz 16 bit stereo).
+    MP3
   deriving (Show, Read, Eq, Ord, Bounded, Enum, Generic)
 
 instance Arbitrary CueFileType where
-  arbitrary = elements [minBound..maxBound]
+  arbitrary = elements [minBound .. maxBound]
 
 -- | A track. Single track can have one or more indices.
-
 data CueTrack = CueTrack
-  { cueTrackDigitalCopyPermitted :: !Bool
-    -- ^ Flag: digital copy permitted.
-  , cueTrackFourChannelAudio     :: !Bool
-    -- ^ Flag: four channel audio.
-  , cueTrackPreemphasisEnabled   :: !Bool
-    -- ^ Flag: pre-emphasis enabled (audio track only).
-  , cueTrackSerialCopyManagement :: !Bool
-    -- ^ Flag: serial copy management system (not supported by all
+  { -- | Flag: digital copy permitted.
+    cueTrackDigitalCopyPermitted :: !Bool,
+    -- | Flag: four channel audio.
+    cueTrackFourChannelAudio :: !Bool,
+    -- | Flag: pre-emphasis enabled (audio track only).
+    cueTrackPreemphasisEnabled :: !Bool,
+    -- | Flag: serial copy management system (not supported by all
     -- recorders).
-  , cueTrackType                 :: !CueTrackType
-    -- ^ Type datatype.
-  , cueTrackIsrc                 :: !(Maybe Isrc)
-    -- ^ The track's International Standard Recording Code (ISRC).
-  , cueTrackTitle                :: !(Maybe CueText)
-    -- ^ Title of the track.
-  , cueTrackPerformer            :: !(Maybe CueText)
-    -- ^ Performer of the track.
-  , cueTrackSongwriter           :: !(Maybe CueText)
-    -- ^ Songwriter of the track.
-  , cueTrackPregap               :: !(Maybe CueTime)
-    -- ^ Track's pregap.
-  , cueTrackPregapIndex          :: !(Maybe CueTime)
-    -- ^ Starting time of track pregap, a.k.a. INDEX 0.
-  , cueTrackIndices              :: !(NonEmpty CueTime)
-    -- ^ Collection of indices for the track starting with index 1. The
+    cueTrackSerialCopyManagement :: !Bool,
+    -- | Type datatype.
+    cueTrackType :: !CueTrackType,
+    -- | The track's International Standard Recording Code (ISRC).
+    cueTrackIsrc :: !(Maybe Isrc),
+    -- | Title of the track.
+    cueTrackTitle :: !(Maybe CueText),
+    -- | Performer of the track.
+    cueTrackPerformer :: !(Maybe CueText),
+    -- | Songwriter of the track.
+    cueTrackSongwriter :: !(Maybe CueText),
+    -- | Track's pregap.
+    cueTrackPregap :: !(Maybe CueTime),
+    -- | Starting time of track pregap, a.k.a. INDEX 0.
+    cueTrackPregapIndex :: !(Maybe CueTime),
+    -- | Collection of indices for the track starting with index 1. The
     -- index specifies the starting time of the track data. Index 1 is the
     -- only index that's stored in the disc's table of contents.
-  , cueTrackPostgap              :: !(Maybe CueTime)
-    -- ^ Track's postgap.
-  } deriving (Show, Eq, Ord, Generic)
+    cueTrackIndices :: !(NonEmpty CueTime),
+    -- | Track's postgap.
+    cueTrackPostgap :: !(Maybe CueTime)
+  }
+  deriving (Show, Eq, Ord, Generic)
 
 instance Arbitrary CueTrack where
-  arbitrary = CueTrack
-    <$> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> arbitrary
-    <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
-    <*> arbitrary
+  arbitrary =
+    CueTrack
+      <$> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> arbitrary
+      <*> scaleDown (NE.fromList . getNonEmpty <$> arbitrary)
+      <*> arbitrary
 
 -- | Track datatype.
-
 data CueTrackType
-  = CueTrackAudio      -- ^ Audio\/Music (2352).
-  | CueTrackCdg        -- ^ Karaoke CD+G (2448).
-  | CueTrackMode1_2048 -- ^ CD-ROM Mode1 data (cooked).
-  | CueTrackMode1_2352 -- ^ CD-ROM Mode1 data (raw).
-  | CueTrackMode2_2336 -- ^ CD-ROM XA Mode2 data.
-  | CueTrackMode2_2352 -- ^ CD-ROM XA Mode2 data.
-  | CueTrackCdi2336    -- ^ CD-I Mode2 data.
-  | CueTrackCdi2352    -- ^ CD-I Mode2 data.
+  = -- | Audio\/Music (2352).
+    CueTrackAudio
+  | -- | Karaoke CD+G (2448).
+    CueTrackCdg
+  | -- | CD-ROM Mode1 data (cooked).
+    CueTrackMode1_2048
+  | -- | CD-ROM Mode1 data (raw).
+    CueTrackMode1_2352
+  | -- | CD-ROM XA Mode2 data.
+    CueTrackMode2_2336
+  | -- | CD-ROM XA Mode2 data.
+    CueTrackMode2_2352
+  | -- | CD-I Mode2 data.
+    CueTrackCdi2336
+  | -- | CD-I Mode2 data.
+    CueTrackCdi2352
   deriving (Show, Read, Eq, Ord, Bounded, Enum, Generic)
 
 instance Arbitrary CueTrackType where
-  arbitrary = elements [minBound..maxBound]
+  arbitrary = elements [minBound .. maxBound]
 
 -- | This datatype is used to indicate duration and position in time. It
 -- contains number of frames. There are 75 frames in one second.
-
 newtype CueTime = CueTime Natural
   deriving (Show, Read, Eq, Ord, Generic)
 
@@ -193,38 +199,39 @@
 -- | Construct 'CueTime' from minutes, seconds, and frames. There are 75
 -- frames per second. If number of seconds or frames is invalid,
 -- 'InvalidSeconds' or 'InvalidFrames' will be thrown.
-
-fromMmSsFf :: MonadThrow m
-  => Natural           -- ^ Number of minutes, no limit here
-  -> Natural           -- ^ Number of seconds, 0–59 inclusive
-  -> Natural           -- ^ Number of frames, 0–74 inclusive
-  -> m CueTime         -- ^ The result
+fromMmSsFf ::
+  MonadThrow m =>
+  -- | Number of minutes, no limit here
+  Natural ->
+  -- | Number of seconds, 0–59 inclusive
+  Natural ->
+  -- | Number of frames, 0–74 inclusive
+  Natural ->
+  -- | The result
+  m CueTime
 fromMmSsFf mm ss ff
-  | ss >= 60  = throwM (InvalidSeconds ss)
-  | ff >= 75  = throwM (InvalidFrames ff)
+  | ss >= 60 = throwM (InvalidSeconds ss)
+  | ff >= 75 = throwM (InvalidFrames ff)
   | otherwise =
-    let ss' = mm * 60 + ss
-        ff' = ss' * 75 + ff
-    in return (CueTime ff')
+      let ss' = mm * 60 + ss
+          ff' = ss' * 75 + ff
+       in return (CueTime ff')
 
 -- | Get minutes, seconds, and frames from a 'CueTime' value.
-
 toMmSsFf :: CueTime -> (Natural, Natural, Natural)
-toMmSsFf (CueTime ff') = (mm,ss,ff)
+toMmSsFf (CueTime ff') = (mm, ss, ff)
   where
     (ss', ff) = ff' `quotRem` 75
-    (mm,  ss) = ss' `quotRem` 60
+    (mm, ss) = ss' `quotRem` 60
 
 -- | Render representation of 'CueTime' in @mm:ss:ff@ format.
-
 showMmSsFf :: CueTime -> Text
 showMmSsFf x = T.pack (printf "%02d:%02d:%02d" mm ss ff)
   where
-    (mm,ss,ff) = toMmSsFf x
+    (mm, ss, ff) = toMmSsFf x
 
 -- | Disc's Media Catalog Number (MCN), must be 13 characters long, all the
 -- characters must be numeric.
-
 newtype Mcn = Mcn Text
   deriving (Eq, Ord, Generic)
 
@@ -236,7 +243,6 @@
 
 -- | Make a 'Mcn'. If the provided 'Text' value is not a valid MCN, throw
 -- the 'InvalidMcnException'.
-
 mkMcn :: MonadThrow m => Text -> m Mcn
 mkMcn x =
   if isValidMcn x
@@ -244,7 +250,6 @@
     else throwM (InvalidMcn x)
 
 -- | Get 'Text' from 'Mcn'.
-
 unMcn :: Mcn -> Text
 unMcn (Mcn x) = x
 
@@ -252,7 +257,6 @@
 -- between 1 and 80 characters as per spec. We also demand that it does not
 -- contain @\"@ and newline characters, as it's not clear from the spec how
 -- to escape them properly.
-
 newtype CueText = CueText Text
   deriving (Eq, Ord, Generic)
 
@@ -264,7 +268,6 @@
 
 -- | Make a 'CueText'. If the provided 'Text' value is not a valid CUE text,
 -- throw the 'InvalidCueText' exception.
-
 mkCueText :: MonadThrow m => Text -> m CueText
 mkCueText x =
   if isValidCueText x
@@ -272,14 +275,12 @@
     else throwM (InvalidCueText x)
 
 -- | Get 'Text' from 'CueText'.
-
 unCueText :: CueText -> Text
 unCueText (CueText x) = x
 
 -- | The track's International Standard Recording Code (ISRC). It must be 12
 -- characters in length. The first five characters are alphanumeric, the
 -- last seven are numeric only.
-
 newtype Isrc = Isrc Text
   deriving (Eq, Ord, Generic)
 
@@ -294,34 +295,31 @@
 
 -- | Make an 'Isrc', if the provided 'Text' value is not a valid ISRC, throw
 -- the 'InvalidIsrc' exception.
-
 mkIsrc :: MonadThrow m => Text -> m Isrc
 mkIsrc x =
-  if T.length x == 12              &&
-     T.all isAlphaNum (T.take 5 x) &&
-     T.all isDigit (T.drop 5 x)
+  if T.length x == 12
+    && T.all isAlphaNum (T.take 5 x)
+    && T.all isDigit (T.drop 5 x)
     then return (Isrc x)
     else throwM (InvalidIsrc x)
 
 -- | Get 'Text' from 'Isrc'.
-
 unIsrc :: Isrc -> Text
 unIsrc (Isrc x) = x
 
 -- | Exception type for the bad things that may happen while you use the
 -- library.
-
 data CueSheetException
-  = InvalidSeconds Natural
-    -- ^ The value is greater than 59 and thus is invalid for 'fromMmSsFf'.
-  | InvalidFrames Natural
-    -- ^ The value is greater than 74 and thus is invalid for 'fromMmSsFf'.
-  | InvalidMcn Text
-    -- ^ Provided text wasn't a correct media catalog number (MCN).
-  | InvalidCueText Text
-    -- ^ Provided text wasn't a valid CUE text.
-  | InvalidIsrc Text
-    -- ^ Provided text wasn't a valid ISRC.
+  = -- | The value is greater than 59 and thus is invalid for 'fromMmSsFf'.
+    InvalidSeconds Natural
+  | -- | The value is greater than 74 and thus is invalid for 'fromMmSsFf'.
+    InvalidFrames Natural
+  | -- | Provided text wasn't a correct media catalog number (MCN).
+    InvalidMcn Text
+  | -- | Provided text wasn't a valid CUE text.
+    InvalidCueText Text
+  | -- | Provided text wasn't a valid ISRC.
+    InvalidIsrc Text
   deriving (Eq, Ord, Show, Read, Generic)
 
 instance Exception CueSheetException
@@ -330,13 +328,11 @@
 -- Helpers
 
 -- | Check if the given 'Text' is a valid MCN.
-
 isValidMcn :: Text -> Bool
 isValidMcn x = T.length x == 13 && T.all isDigit x
 
 -- | Check if the given 'Text' has valid length and contents to be used in a
 -- CUE sheet as performer, title, etc.
-
 isValidCueText :: Text -> Bool
 isValidCueText x = l >= 1 && l <= 80 && T.all f x
   where
@@ -345,17 +341,14 @@
 
 -- | A variant of 'Data.Char.IsAlphaNum' that only permits ASCII letter
 -- chars.
-
 isAlphaNum :: Char -> Bool
 isAlphaNum a = isAscii a && (isDigit a || isLetter a)
 
 -- | Scale down size of 'arbitrary'-generated stuff.
-
 scaleDown :: Gen a -> Gen a
 scaleDown = scale (`quot` 3)
 
 -- | File path generator.
-
 filepath :: Gen FilePath
 filepath = listOf (arbitrary `suchThat` windowsLikesIt)
   where
diff --git a/cue-sheet.cabal b/cue-sheet.cabal
--- a/cue-sheet.cabal
+++ b/cue-sheet.cabal
@@ -1,78 +1,88 @@
-name:                 cue-sheet
-version:              2.0.1
-cabal-version:        1.18
-tested-with:          GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3
-license:              BSD3
-license-file:         LICENSE.md
-author:               Mark Karpov <markkarpov92@gmail.com>
-maintainer:           Mark Karpov <markkarpov92@gmail.com>
-homepage:             https://github.com/mrkkrp/cue-sheet
-bug-reports:          https://github.com/mrkkrp/cue-sheet/issues
-category:             Audio
-synopsis:             Support for construction, rendering, and parsing of CUE sheets
-build-type:           Simple
-description:          Support for construction, rendering, and parsing of CUE sheets.
-extra-doc-files:      CHANGELOG.md
-                    , README.md
-data-files:           cue-sheet-samples/*.cue
+cabal-version:   2.4
+name:            cue-sheet
+version:         2.0.2
+license:         BSD-3-Clause
+license-file:    LICENSE.md
+maintainer:      Mark Karpov <markkarpov92@gmail.com>
+author:          Mark Karpov <markkarpov92@gmail.com>
+tested-with:     ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.1
+homepage:        https://github.com/mrkkrp/cue-sheet
+bug-reports:     https://github.com/mrkkrp/cue-sheet/issues
+synopsis:
+    Support for construction, rendering, and parsing of CUE sheets
 
+description:
+    Support for construction, rendering, and parsing of CUE sheets.
+
+category:        Audio
+build-type:      Simple
+data-files:      cue-sheet-samples/*.cue
+extra-doc-files:
+    CHANGELOG.md
+    README.md
+
 source-repository head
-  type:               git
-  location:           https://github.com/mrkkrp/cue-sheet.git
+    type:     git
+    location: https://github.com/mrkkrp/cue-sheet.git
 
 flag dev
-  description:        Turn on development settings.
-  manual:             True
-  default:            False
+    description: Turn on development settings.
+    default:     False
+    manual:      True
 
 library
-  build-depends:      QuickCheck       >= 2.4    && < 3.0
-                    , base             >= 4.8    && < 5.0
-                    , bytestring       >= 0.10.8 && < 0.11
-                    , containers       >= 0.5    && < 0.7
-                    , exceptions       >= 0.6    && < 0.11
-                    , megaparsec       >= 7.0    && < 8.0
-                    , mtl              >= 2.0    && < 3.0
-                    , text             >= 0.2    && < 1.3
-  if !impl(ghc >= 8.0)
-    build-depends:    semigroups       == 0.18.*
-  exposed-modules:    Text.CueSheet
-                    , Text.CueSheet.Types
-                    , Text.CueSheet.Parser
-                    , Text.CueSheet.Render
-  if flag(dev)
-    ghc-options:      -Wall -Werror
-  else
-    ghc-options:      -O2 -Wall
-  if flag(dev) && impl(ghc >= 8.0)
-    ghc-options:      -Wcompat
-                      -Wincomplete-record-updates
-                      -Wincomplete-uni-patterns
-                      -Wnoncanonical-monad-instances
-                      -Wnoncanonical-monadfail-instances
-  default-language:   Haskell2010
+    exposed-modules:
+        Text.CueSheet
+        Text.CueSheet.Types
+        Text.CueSheet.Parser
+        Text.CueSheet.Render
 
+    default-language: Haskell2010
+    build-depends:
+        QuickCheck >=2.4 && <3.0,
+        base >=4.13 && <5.0,
+        bytestring >=0.10.8 && <0.12,
+        containers >=0.5 && <0.7,
+        exceptions >=0.6 && <0.11,
+        megaparsec >=7.0 && <10.0,
+        mtl >=2.0 && <3.0,
+        text >=0.2 && <1.3
+
+    if flag(dev)
+        ghc-options: -Wall -Werror
+
+    else
+        ghc-options: -O2 -Wall
+
+    if flag(dev)
+        ghc-options:
+            -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns
+            -Wnoncanonical-monad-instances
+
 test-suite tests
-  main-is:            Spec.hs
-  other-modules:      Text.CueSheet.ParserSpec
-                    , Text.CueSheet.RenderSpec
-                    , Text.CueSheet.TypesSpec
-  hs-source-dirs:     tests
-  type:               exitcode-stdio-1.0
-  build-depends:      QuickCheck       >= 2.4    && < 3.0
-                    , base             >= 4.8    && < 5.0
-                    , bytestring       >= 0.10.8 && < 0.11
-                    , cue-sheet
-                    , exceptions       >= 0.6    && < 0.11
-                    , hspec            >= 2.0    && < 3.0
-                    , hspec-megaparsec >= 2.0    && < 3.0
-                    , megaparsec       >= 7.0    && < 8.0
-                    , text             >= 0.2    && < 1.3
-  build-tools:        hspec-discover   >= 2.0    && < 3.0
-  if !impl(ghc >= 8.0)
-    build-depends:    semigroups       == 0.18.*
-  if flag(dev)
-    ghc-options:      -Wall -Werror
-  else
-    ghc-options:      -O2 -Wall
-  default-language:   Haskell2010
+    type:               exitcode-stdio-1.0
+    main-is:            Spec.hs
+    build-tool-depends: hspec-discover:hspec-discover >=2.0 && <3.0
+    hs-source-dirs:     tests
+    other-modules:
+        Text.CueSheet.ParserSpec
+        Text.CueSheet.RenderSpec
+        Text.CueSheet.TypesSpec
+
+    default-language:   Haskell2010
+    build-depends:
+        QuickCheck >=2.4 && <3.0,
+        base >=4.13 && <5.0,
+        bytestring >=0.10.8 && <0.12,
+        cue-sheet,
+        exceptions >=0.6 && <0.11,
+        hspec >=2.0 && <3.0,
+        hspec-megaparsec >=2.0 && <3.0,
+        megaparsec >=7.0 && <10.0,
+        text >=0.2 && <1.3
+
+    if flag(dev)
+        ghc-options: -Wall -Werror
+
+    else
+        ghc-options: -O2 -Wall
diff --git a/tests/Text/CueSheet/ParserSpec.hs b/tests/Text/CueSheet/ParserSpec.hs
--- a/tests/Text/CueSheet/ParserSpec.hs
+++ b/tests/Text/CueSheet/ParserSpec.hs
@@ -1,19 +1,16 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-module Text.CueSheet.ParserSpec
-  ( spec )
-where
+module Text.CueSheet.ParserSpec (spec) where
 
 import Control.Monad.Catch
 import Data.ByteString (ByteString)
-import Data.Monoid ((<>))
+import qualified Data.ByteString as B
+import qualified Data.List.NonEmpty as NE
 import Test.Hspec
 import Test.Hspec.Megaparsec
 import Text.CueSheet.Parser
 import Text.CueSheet.Types
 import Text.Megaparsec
-import qualified Data.ByteString    as B
-import qualified Data.List.NonEmpty as NE
 
 spec :: Spec
 spec =
@@ -32,226 +29,305 @@
       parseCueSheet "" bs `shouldParse` sheet
     it "at least one file should be declared" $ do
       bs <- B.readFile "cue-sheet-samples/parser-missing-file.cue"
-      let es = foldMap etoks
-            [ "CATALOG"
-            , "CDTEXTFILE"
-            , "FILE"
-            , "PERFORMER"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        err 67 (ueof <> es)
+      let es =
+            foldMap
+              etoks
+              [ "CATALOG",
+                "CDTEXTFILE",
+                "FILE",
+                "PERFORMER",
+                "REM",
+                "SONGWRITER",
+                "TITLE"
+              ]
+      parseCueSheet "" bs
+        `shouldFailWith` err 67 (ueof <> es)
     it "at least one track should be declared" $ do
       bs <- B.readFile "cue-sheet-samples/parser-missing-track.cue"
-      parseCueSheet "" bs `shouldFailWith`
-        err 109 (ueof <> etoks "REM" <> etoks "TRACK")
+      parseCueSheet "" bs
+        `shouldFailWith` err 109 (ueof <> etoks "REM" <> etoks "TRACK")
     it "at least one non-zero index should be declared" $ do
       bs <- B.readFile "cue-sheet-samples/parser-missing-index.cue"
       let e = wrappedTrivial (ueof <> etoks "INDEX" <> etoks "REM")
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 174 (cstm (Eec (Just 1) e))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 174 (cstm (Eec (Just 1) e))
     it "parses a normal CUE file without issues" $ do
       bs <- B.readFile "cue-sheet-samples/parser-normal.cue"
       sheet <- normalCueSheet
       parseCueSheet "" bs `shouldParse` sheet
     it "rejects invalid catalog number" $ do
       bs <- B.readFile "cue-sheet-samples/parser-invalid-catalog.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 8
-        (cstm (Eec Nothing (CueParserInvalidCatalog "123")))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          8
+          (cstm (Eec Nothing (CueParserInvalidCatalog "123")))
     it "rejects invalid CUE text" $ do
       bs <- B.readFile "cue-sheet-samples/parser-invalid-text.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 10
-        (cstm (Eec Nothing (CueParserInvalidCueText "")))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          10
+          (cstm (Eec Nothing (CueParserInvalidCueText "")))
     it "detects and reports tracks that appear out of order" $ do
       bs <- B.readFile "cue-sheet-samples/parser-track-out-of-order.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 182
-        (cstm (Eec Nothing CueParserTrackOutOfOrder))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          182
+          (cstm (Eec Nothing CueParserTrackOutOfOrder))
     it "rejects invalid ISRC values" $ do
       bs <- B.readFile "cue-sheet-samples/parser-invalid-isrc.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 161
-        (cstm (Eec (Just 3) (CueParserInvalidTrackIsrc "123")))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          161
+          (cstm (Eec (Just 3) (CueParserInvalidTrackIsrc "123")))
     it "rejects invalid number of seconds" $ do
       bs <- B.readFile "cue-sheet-samples/parser-invalid-seconds.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 168
-        (cstm (Eec (Just 1) (CueParserInvalidSeconds 61)))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          168
+          (cstm (Eec (Just 1) (CueParserInvalidSeconds 61)))
     it "rejects invalid number of frames" $ do
       bs <- B.readFile "cue-sheet-samples/parser-invalid-frames.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 171
-        (cstm (Eec (Just 1) (CueParserInvalidFrames 77)))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          171
+          (cstm (Eec (Just 1) (CueParserInvalidFrames 77)))
     it "detects and reports indices that appear out of order" $ do
       bs <- B.readFile "cue-sheet-samples/parser-index-out-of-order.cue"
-      parseCueSheet "" bs `shouldFailWith` errFancy 162
-        (cstm (Eec (Just 1) CueParserTrackIndexOutOfOrder))
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy
+          162
+          (cstm (Eec (Just 1) CueParserTrackIndexOutOfOrder))
     it "rejects duplicate CATALOG command" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-catalog.cue"
-      let es = utoks "CATA" <> foldMap etoks
-            [ "CDTEXTFILE"
-            , "FILE"
-            , "PERFORMER"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
+      let es =
+            utoks "CATA"
+              <> foldMap
+                etoks
+                [ "CDTEXTFILE",
+                  "FILE",
+                  "PERFORMER",
+                  "REM",
+                  "SONGWRITER",
+                  "TITLE"
+                ]
       parseCueSheet "" bs `shouldFailWith` err 22 es
     it "rejects duplicate CDTEXTFILE command" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-cdtextfile.cue"
-      let es = utoks "CDTE" <> foldMap etoks
-            [ "CATALOG"
-            , "FILE"
-            , "PERFORMER"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
+      let es =
+            utoks "CDTE"
+              <> foldMap
+                etoks
+                [ "CATALOG",
+                  "FILE",
+                  "PERFORMER",
+                  "REM",
+                  "SONGWRITER",
+                  "TITLE"
+                ]
       parseCueSheet "" bs `shouldFailWith` err 23 es
     it "rejects duplicate PERFORMER command" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-performer.cue"
-      let es = utoks "PERF" <> foldMap etoks
-            [ "CATALOG"
-            , "CDTEXTFILE"
-            , "FILE"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
+      let es =
+            utoks "PERF"
+              <> foldMap
+                etoks
+                [ "CATALOG",
+                  "CDTEXTFILE",
+                  "FILE",
+                  "REM",
+                  "SONGWRITER",
+                  "TITLE"
+                ]
       parseCueSheet "" bs `shouldFailWith` err 30 es
     it "rejects duplicate TITLE command" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-title.cue"
-      let es = utoks "TITL" <> foldMap etoks
-            [ "CATALOG"
-            , "CDTEXTFILE"
-            , "FILE"
-            , "PERFORMER"
-            , "REM"
-            , "SONGWRITER" ]
+      let es =
+            utoks "TITL"
+              <> foldMap
+                etoks
+                [ "CATALOG",
+                  "CDTEXTFILE",
+                  "FILE",
+                  "PERFORMER",
+                  "REM",
+                  "SONGWRITER"
+                ]
       parseCueSheet "" bs `shouldFailWith` err 17 es
     it "rejects duplicate SONGWRITER command" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-songwriter.cue"
-      let es = utoks "SONG" <> foldMap etoks
-            [ "CATALOG"
-            , "CDTEXTFILE"
-            , "FILE"
-            , "PERFORMER"
-            , "REM"
-            , "TITLE" ]
+      let es =
+            utoks "SONG"
+              <> foldMap
+                etoks
+                [ "CATALOG",
+                  "CDTEXTFILE",
+                  "FILE",
+                  "PERFORMER",
+                  "REM",
+                  "TITLE"
+                ]
       parseCueSheet "" bs `shouldFailWith` err 18 es
     it "rejects duplicate FLAGS command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-flags.cue"
-      let es = wrappedTrivial $ utoks "FLAGS" <> foldMap etoks
-            [ "INDEX"
-            , "ISRC"
-            , "PERFORMER"
-            , "PREGAP"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 144 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "FLAGS"
+                <> foldMap
+                  etoks
+                  [ "INDEX",
+                    "ISRC",
+                    "PERFORMER",
+                    "PREGAP",
+                    "REM",
+                    "SONGWRITER",
+                    "TITLE"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 144 (cstm (Eec (Just 1) es))
     it "rejects duplicate ISRC command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-isrc.cue"
-      let es = wrappedTrivial $ utoks "ISRC " <> foldMap etoks
-            [ "FLAGS"
-            , "INDEX"
-            , "PERFORMER"
-            , "PREGAP"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 152 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "ISRC "
+                <> foldMap
+                  etoks
+                  [ "FLAGS",
+                    "INDEX",
+                    "PERFORMER",
+                    "PREGAP",
+                    "REM",
+                    "SONGWRITER",
+                    "TITLE"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 152 (cstm (Eec (Just 1) es))
     it "rejects duplicate PERFORMER command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-performer.cue"
-      let es = wrappedTrivial $ utoks "PERFO" <> foldMap etoks
-            [ "FLAGS"
-            , "INDEX"
-            , "ISRC"
-            , "PREGAP"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 156 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "PERFO"
+                <> foldMap
+                  etoks
+                  [ "FLAGS",
+                    "INDEX",
+                    "ISRC",
+                    "PREGAP",
+                    "REM",
+                    "SONGWRITER",
+                    "TITLE"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 156 (cstm (Eec (Just 1) es))
     it "rejects duplicate TITLE command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-title.cue"
-      let es = wrappedTrivial $ utoks "TITLE" <> foldMap etoks
-            [ "FLAGS"
-            , "INDEX"
-            , "ISRC"
-            , "PERFORMER"
-            , "PREGAP"
-            , "REM"
-            , "SONGWRITER" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 146 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "TITLE"
+                <> foldMap
+                  etoks
+                  [ "FLAGS",
+                    "INDEX",
+                    "ISRC",
+                    "PERFORMER",
+                    "PREGAP",
+                    "REM",
+                    "SONGWRITER"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 146 (cstm (Eec (Just 1) es))
     it "rejects duplicate SONGWRITER command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-songwriter.cue"
-      let es = wrappedTrivial $ utoks "SONGW" <> foldMap etoks
-            [ "FLAGS"
-            , "INDEX"
-            , "ISRC"
-            , "PERFORMER"
-            , "PREGAP"
-            , "REM"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 150 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "SONGW"
+                <> foldMap
+                  etoks
+                  [ "FLAGS",
+                    "INDEX",
+                    "ISRC",
+                    "PERFORMER",
+                    "PREGAP",
+                    "REM",
+                    "TITLE"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 150 (cstm (Eec (Just 1) es))
     it "rejects duplicate PREGAP command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-pregap.cue"
-      let es = wrappedTrivial $ utoks "PREGA" <> foldMap etoks
-            [ "FLAGS"
-            , "INDEX"
-            , "ISRC"
-            , "PERFORMER"
-            , "REM"
-            , "SONGWRITER"
-            , "TITLE" ]
-      parseCueSheet "" bs `shouldFailWith`
-        errFancy 176 (cstm (Eec (Just 1) es))
+      let es =
+            wrappedTrivial $
+              utoks "PREGA"
+                <> foldMap
+                  etoks
+                  [ "FLAGS",
+                    "INDEX",
+                    "ISRC",
+                    "PERFORMER",
+                    "REM",
+                    "SONGWRITER",
+                    "TITLE"
+                  ]
+      parseCueSheet "" bs
+        `shouldFailWith` errFancy 176 (cstm (Eec (Just 1) es))
     it "rejects duplicate POSTGAP command (in track)" $ do
       bs <- B.readFile "cue-sheet-samples/parser-duplicate-track-postgap.cue"
-      let es = foldMap etoks
-            [ "FILE"
-            , "REM"
-            , "TRACK" ]
-      parseCueSheet "" bs `shouldFailWith`
-        err 199 (utok 80 <> es <> eeof)
+      let es =
+            foldMap
+              etoks
+              [ "FILE",
+                "REM",
+                "TRACK"
+              ]
+      parseCueSheet "" bs
+        `shouldFailWith` err 199 (utok 80 <> es <> eeof)
 
 testSheet :: MonadThrow m => m CueSheet
 testSheet = do
-  performer  <- mkCueText "Faithless"
-  title      <- mkCueText "Live in Berlin"
+  performer <- mkCueText "Faithless"
+  title <- mkCueText "Live in Berlin"
   trackTitle <- mkCueText "Reverence"
-  return CueSheet
-    { cueCatalog    = Nothing
-    , cueCdTextFile = Nothing
-    , cuePerformer  = Just performer
-    , cueTitle      = Just title
-    , cueSongwriter = Nothing
-    , cueFirstTrackNumber = 1
-    , cueFiles      = NE.fromList
-      [ CueFile
-        { cueFileName = "Faithless - Live in Berlin.mp3"
-        , cueFileType = MP3
-        , cueFileTracks = NE.fromList
-          [ CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just trackTitle
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList
-              [CueTime 3, CueTime 151]
-            , cueTrackPostgap              = Nothing } ] } ] }
+  return
+    CueSheet
+      { cueCatalog = Nothing,
+        cueCdTextFile = Nothing,
+        cuePerformer = Just performer,
+        cueTitle = Just title,
+        cueSongwriter = Nothing,
+        cueFirstTrackNumber = 1,
+        cueFiles =
+          NE.fromList
+            [ CueFile
+                { cueFileName = "Faithless - Live in Berlin.mp3",
+                  cueFileType = MP3,
+                  cueFileTracks =
+                    NE.fromList
+                      [ CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just trackTitle,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices =
+                              NE.fromList
+                                [CueTime 3, CueTime 151],
+                            cueTrackPostgap = Nothing
+                          }
+                      ]
+                }
+            ]
+      }
 
 normalCueSheet :: MonadThrow m => m CueSheet
 normalCueSheet = do
-  performer   <- mkCueText "Faithless"
-  catalog     <- mkMcn "1112223334445"
-  title       <- mkCueText "Live in Berlin"
+  performer <- mkCueText "Faithless"
+  catalog <- mkMcn "1112223334445"
+  title <- mkCueText "Live in Berlin"
   track1Title <- mkCueText "Reverence"
   track2Title <- mkCueText "She's My Baby"
   track3Title <- mkCueText "Take the Long Way Home"
@@ -260,142 +336,156 @@
   track6Title <- mkCueText "Salva Mea"
   track7Title <- mkCueText "Dirty Old Man"
   track8Title <- mkCueText "God Is a DJ"
-  return CueSheet
-    { cueCatalog    = Just catalog
-    , cueCdTextFile = Just "blah-blah.txt"
-    , cuePerformer  = Just performer
-    , cueTitle      = Just title
-    , cueSongwriter = Nothing
-    , cueFirstTrackNumber = 1
-    , cueFiles      = NE.fromList
-      [ CueFile
-        { cueFileName = "Faithless - Live in Berlin.mp3"
-        , cueFileType = MP3
-        , cueFileTracks = NE.fromList
-          [ CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track1Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Just (CueTime 75)
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 0]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track2Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 30150]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track3Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 49050]
-            , cueTrackPostgap              = Just (CueTime 76) }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track4Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList
-              [CueTime 76800, CueTime 76805]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = True
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track5Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 115800]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track6Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 138750]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track7Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 172800]
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Nothing
-            , cueTrackTitle                = Just track8Title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = NE.fromList [CueTime 191625]
-            , cueTrackPostgap              = Nothing } ] } ] }
+  return
+    CueSheet
+      { cueCatalog = Just catalog,
+        cueCdTextFile = Just "blah-blah.txt",
+        cuePerformer = Just performer,
+        cueTitle = Just title,
+        cueSongwriter = Nothing,
+        cueFirstTrackNumber = 1,
+        cueFiles =
+          NE.fromList
+            [ CueFile
+                { cueFileName = "Faithless - Live in Berlin.mp3",
+                  cueFileType = MP3,
+                  cueFileTracks =
+                    NE.fromList
+                      [ CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track1Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Just (CueTime 75),
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 0],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track2Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 30150],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track3Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 49050],
+                            cueTrackPostgap = Just (CueTime 76)
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track4Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices =
+                              NE.fromList
+                                [CueTime 76800, CueTime 76805],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = True,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track5Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 115800],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track6Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 138750],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track7Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 172800],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Nothing,
+                            cueTrackTitle = Just track8Title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = NE.fromList [CueTime 191625],
+                            cueTrackPostgap = Nothing
+                          }
+                      ]
+                }
+            ]
+      }
 
 -- | Construct 'CueParserFailure' from given @'ET' 'Word8'@ thing.
-
 wrappedTrivial :: ET ByteString -> CueParserFailure
 wrappedTrivial xs =
   case err 0 xs of
     TrivialError _ us es -> CueParserTrivialError us es
-    _                    -> error "Ooops!"
+    _ -> error "Ooops!"
 
 -- | Quickly make a custom error component.
-
 cstm :: e -> EF e
 cstm = fancy . ErrorCustom
 {-# INLINE cstm #-}
diff --git a/tests/Text/CueSheet/RenderSpec.hs b/tests/Text/CueSheet/RenderSpec.hs
--- a/tests/Text/CueSheet/RenderSpec.hs
+++ b/tests/Text/CueSheet/RenderSpec.hs
@@ -1,18 +1,16 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-module Text.CueSheet.RenderSpec
-  ( spec )
-where
+module Text.CueSheet.RenderSpec (spec) where
 
 import Control.Monad.Catch
+import qualified Data.ByteString.Lazy as BL
 import Data.List.NonEmpty (NonEmpty (..))
+import qualified Data.List.NonEmpty as NE
 import Test.Hspec
 import Test.QuickCheck
 import Text.CueSheet.Parser
 import Text.CueSheet.Render
 import Text.CueSheet.Types
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.List.NonEmpty   as NE
 
 spec :: Spec
 spec =
@@ -21,11 +19,11 @@
       property $ \csrf cueSheet -> do
         let r = renderCueSheet csrf cueSheet
             f x = if csrf then BL.take (BL.length x - 1) x else x
-        BL.split 10 r `shouldNotSatisfy`
-          any ((" " `BL.isSuffixOf`) . f)
+        BL.split 10 r
+          `shouldNotSatisfy` any ((" " `BL.isSuffixOf`) . f)
     it "always ends with the specified new line sequence" $
       property $ \csrf cueSheet -> do
-        let r   = renderCueSheet csrf cueSheet
+        let r = renderCueSheet csrf cueSheet
             eol = if csrf then "\r\n" else "\n"
         r `shouldSatisfy` (eol `BL.isSuffixOf`)
     it "doesn't look too bad" $ do
@@ -38,88 +36,99 @@
           `shouldBe` Right cueSheet
 
 -- | A manually constructed testing CUE sheet.
-
 testCueSheet :: MonadThrow m => m CueSheet
 testCueSheet = do
-  mcn        <- mkMcn "1112223334445"
-  performer  <- mkCueText "The Famous Foobar"
-  title      <- mkCueText "Bobla Fett"
+  mcn <- mkMcn "1112223334445"
+  performer <- mkCueText "The Famous Foobar"
+  title <- mkCueText "Bobla Fett"
   songwriter <- mkCueText "Paul"
-  isrc       <- mkIsrc    "agree1234567"
-  pregap     <- fromMmSsFf 1 0 13
-  index      <- fromMmSsFf 0 0 15
-  postgap    <- fromMmSsFf 0 8 9
-  return CueSheet
-    { cueCatalog    = Just mcn
-    , cueCdTextFile = Just "/home/mark/mycdtextfile.txt"
-    , cuePerformer  = Just performer
-    , cueTitle      = Just title
-    , cueSongwriter = Just songwriter
-    , cueFirstTrackNumber = 1
-    , cueFiles      = NE.fromList
-      [ CueFile
-        { cueFileName   = "the-famous-foobar-cd1.flac"
-        , cueFileType   = Wave
-        , cueFileTracks = NE.fromList
-          [ CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = True
-            , cueTrackSerialCopyManagement = True
-            , cueTrackType                 = CueTrackAudio
-            , cueTrackIsrc                 = Just isrc
-            , cueTrackTitle                = Just title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = index :| []
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = True
-            , cueTrackFourChannelAudio     = True
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackCdg
-            , cueTrackIsrc                 = Just isrc
-            , cueTrackTitle                = Just title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Just pregap
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = index :| []
-            , cueTrackPostgap              = Just postgap } ] }
-      , CueFile
-        { cueFileName   = "the-famous-foobar-cd2.mp3"
-        , cueFileType   = MP3
-        , cueFileTracks = NE.fromList
-          [ CueTrack
-            { cueTrackDigitalCopyPermitted = False
-            , cueTrackFourChannelAudio     = False
-            , cueTrackPreemphasisEnabled   = False
-            , cueTrackSerialCopyManagement = False
-            , cueTrackType                 = CueTrackMode1_2048
-            , cueTrackIsrc                 = Just isrc
-            , cueTrackTitle                = Just title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = index :| []
-            , cueTrackPostgap              = Nothing }
-          , CueTrack
-            { cueTrackDigitalCopyPermitted = True
-            , cueTrackFourChannelAudio     = True
-            , cueTrackPreemphasisEnabled   = True
-            , cueTrackSerialCopyManagement = True
-            , cueTrackType                 = CueTrackMode2_2336
-            , cueTrackIsrc                 = Just isrc
-            , cueTrackTitle                = Just title
-            , cueTrackPerformer            = Just performer
-            , cueTrackSongwriter           = Nothing
-            , cueTrackPregap               = Nothing
-            , cueTrackPregapIndex          = Nothing
-            , cueTrackIndices              = index :| []
-            , cueTrackPostgap              = Nothing } ] }
-      ]
-    }
+  isrc <- mkIsrc "agree1234567"
+  pregap <- fromMmSsFf 1 0 13
+  index <- fromMmSsFf 0 0 15
+  postgap <- fromMmSsFf 0 8 9
+  return
+    CueSheet
+      { cueCatalog = Just mcn,
+        cueCdTextFile = Just "/home/mark/mycdtextfile.txt",
+        cuePerformer = Just performer,
+        cueTitle = Just title,
+        cueSongwriter = Just songwriter,
+        cueFirstTrackNumber = 1,
+        cueFiles =
+          NE.fromList
+            [ CueFile
+                { cueFileName = "the-famous-foobar-cd1.flac",
+                  cueFileType = Wave,
+                  cueFileTracks =
+                    NE.fromList
+                      [ CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = True,
+                            cueTrackSerialCopyManagement = True,
+                            cueTrackType = CueTrackAudio,
+                            cueTrackIsrc = Just isrc,
+                            cueTrackTitle = Just title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = index :| [],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = True,
+                            cueTrackFourChannelAudio = True,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackCdg,
+                            cueTrackIsrc = Just isrc,
+                            cueTrackTitle = Just title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Just pregap,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = index :| [],
+                            cueTrackPostgap = Just postgap
+                          }
+                      ]
+                },
+              CueFile
+                { cueFileName = "the-famous-foobar-cd2.mp3",
+                  cueFileType = MP3,
+                  cueFileTracks =
+                    NE.fromList
+                      [ CueTrack
+                          { cueTrackDigitalCopyPermitted = False,
+                            cueTrackFourChannelAudio = False,
+                            cueTrackPreemphasisEnabled = False,
+                            cueTrackSerialCopyManagement = False,
+                            cueTrackType = CueTrackMode1_2048,
+                            cueTrackIsrc = Just isrc,
+                            cueTrackTitle = Just title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = index :| [],
+                            cueTrackPostgap = Nothing
+                          },
+                        CueTrack
+                          { cueTrackDigitalCopyPermitted = True,
+                            cueTrackFourChannelAudio = True,
+                            cueTrackPreemphasisEnabled = True,
+                            cueTrackSerialCopyManagement = True,
+                            cueTrackType = CueTrackMode2_2336,
+                            cueTrackIsrc = Just isrc,
+                            cueTrackTitle = Just title,
+                            cueTrackPerformer = Just performer,
+                            cueTrackSongwriter = Nothing,
+                            cueTrackPregap = Nothing,
+                            cueTrackPregapIndex = Nothing,
+                            cueTrackIndices = index :| [],
+                            cueTrackPostgap = Nothing
+                          }
+                      ]
+                }
+            ]
+      }
diff --git a/tests/Text/CueSheet/TypesSpec.hs b/tests/Text/CueSheet/TypesSpec.hs
--- a/tests/Text/CueSheet/TypesSpec.hs
+++ b/tests/Text/CueSheet/TypesSpec.hs
@@ -1,13 +1,11 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-module Text.CueSheet.TypesSpec
-  ( spec )
-where
+module Text.CueSheet.TypesSpec (spec) where
 
+import qualified Data.Text as T
 import Test.Hspec
 import Test.QuickCheck
 import Text.CueSheet.Types
-import qualified Data.Text as T
 
 spec :: Spec
 spec =
@@ -30,14 +28,14 @@
       it "produces the correct result" $ do
         fromMmSsFf 0 13 66 `shouldReturn` CueTime 1041
         fromMmSsFf 3 44 10 `shouldReturn` CueTime 16810
-        fromMmSsFf 9  0  0 `shouldReturn` CueTime 40500
+        fromMmSsFf 9 0 0 `shouldReturn` CueTime 40500
     describe "showMmSsFf" $
       it "works correctly" $ do
         let f mm ss ff = showMmSsFf <$> fromMmSsFf mm ss ff
-        f   0 12  3 `shouldReturn` "00:12:03"
-        f   9 17 73 `shouldReturn` "09:17:73"
-        f  99 59 74 `shouldReturn` "99:59:74"
-        f 100  0 35 `shouldReturn` "100:00:35"
+        f 0 12 3 `shouldReturn` "00:12:03"
+        f 9 17 73 `shouldReturn` "09:17:73"
+        f 99 59 74 `shouldReturn` "99:59:74"
+        f 100 0 35 `shouldReturn` "100:00:35"
     describe "mkMcn" $ do
       context "when input value is a valid MCN" $
         it "returns the MCN all right" $
@@ -45,8 +43,8 @@
             mkMcn (unMcn mcn) `shouldReturn` mcn
       context "when input value is invalid" $
         it "throws the correct exception" $ do
-          mkMcn "something"     `shouldThrow` (== InvalidMcn "something")
-          mkMcn "123123123"     `shouldThrow` (== InvalidMcn "123123123")
+          mkMcn "something" `shouldThrow` (== InvalidMcn "something")
+          mkMcn "123123123" `shouldThrow` (== InvalidMcn "123123123")
           mkMcn "111222333444a" `shouldThrow` (== InvalidMcn "111222333444a")
     describe "mkCueText" $ do
       context "when input value is a valid CUE text" $
@@ -74,6 +72,6 @@
             mkIsrc (unIsrc isrc) `shouldReturn` isrc
       context "when input value is invalid" $
         it "throws the correct exception" $ do
-          mkIsrc "a"            `shouldThrow` (== InvalidIsrc "a")
+          mkIsrc "a" `shouldThrow` (== InvalidIsrc "a")
           mkIsrc "12323asoent8" `shouldThrow` (== InvalidIsrc "12323asoent8")
           mkIsrc "aoe8u120997u" `shouldThrow` (== InvalidIsrc "aoe8u120997u")
