diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -10,11 +10,23 @@
 
 Available on [Hackage as `sbp`](http://hackage.haskell.org/package/sbp).
 
-To install from Hackage using `stack`:
+The library supports building against Stackage LTS-5, LTS-6, and LTS-8. To
+install from Hackage using `stack`:
 
-    $ stack install --resolver lts-6.25 sbp
-    
-Note that we explicitly specify the `lts-6.25` resolver, `libsbp` may fail to build with more recent resolvers.
+    $ stack install --resolver lts-6.35 sbp # (LTS-6)
+
+or
+
+    $ stack install --resolver lts-8.21 sbp # (LTS-8)
+
+or
+
+    $ stack install --resolver lts-5.18 sbp # (LTS-5)
+
+Note that we explicitly specify the resolvers to use, as installing `libsbp` may
+fail to build with more recent resolvers.
+
+Building with cabal is possible but not supported and may fail to build.
 
 ## Setup
 
diff --git a/bench/Bench.hs b/bench/Bench.hs
deleted file mode 100644
--- a/bench/Bench.hs
+++ /dev/null
@@ -1,113 +0,0 @@
-import BasicPrelude
-import Criterion.Main
-import qualified Data.Aeson as A
-import qualified Data.Binary as B
-import qualified Data.ByteString.Base64 as Base64
-import qualified Data.ByteString.Lazy as LBS
-import SwiftNav.SBP
-
--- | Message length and dispatch overhead for SBP serialization and
--- deserialization (on local developer Macbook Pro).
---
--- benchmarking JSON encoding/Encode short message (acq)
--- time                 3.711 μs   (3.538 μs .. 4.015 μs)
--- benchmarking JSON encoding/Encode wrapped message
--- time                 7.883 μs   (7.607 μs .. 8.135 μs)
--- benchmarking JSON encoding/Encode longer message (obs)
--- time                 15.04 μs   (14.59 μs .. 15.45 μs)
--- benchmarking JSON encoding/Encode longer wrapped message
--- time                 20.90 μs   (20.49 μs .. 21.40 μs)
--- benchmarking JSON encoding/Encode longer message (base)
--- time                 3.762 μs   (3.511 μs .. 4.082 μs)
--- benchmarking JSON encoding/Encode longer wrapped message
--- time                 6.746 μs   (6.564 μs .. 7.059 μs)
--- benchmarking Binary encoding/Encode short message (acq)
--- time                 4.913 μs   (4.425 μs .. 5.342 μs)
--- benchmarking Binary encoding/Encode wrapped message
--- time                 6.213 μs   (5.495 μs .. 7.044 μs)
--- benchmarking Binary encoding/Encode longer message (obs)
--- time                 5.055 μs   (4.596 μs .. 5.542 μs)
--- benchmarking Binary encoding/Encode longer wrapped message
--- time                 5.200 μs   (4.733 μs .. 5.698 μs)
--- benchmarking Binary encoding/Encode longer message (base)
--- time                 6.353 μs   (6.058 μs .. 6.676 μs)
--- benchmarking Binary encoding/Encode longer wrapped message
--- time                 4.585 μs   (4.146 μs .. 5.081 μs)
--- benchmarking Binary decoding/Decode short message
--- time                 1.008 μs   (976.0 ns .. 1.046 μs)
--- benchmarking Binary decoding/Decode longer message
--- time                 3.211 μs   (2.989 μs .. 3.449 μs)
-
-msgToEncode :: MsgAcqResult
-msgToEncode = MsgAcqResult 2 2 2 3
-
-msgToEncode' :: SBPMsg
-msgToEncode' = SBPMsgAcqResult msgToEncode (toSBP msgToEncode defaultSender)
-
-msgToEncode1 :: MsgBaselineNed
-msgToEncode1 = MsgBaselineNed 100000 1 1 1 1 1 1 1
-
-msgToEncode1' :: SBPMsg
-msgToEncode1' = SBPMsgBaselineNed msgToEncode1 (toSBP msgToEncode1 defaultSender)
-
-longMsgToEncode :: MsgObs
-longMsgToEncode = MsgObs (ObservationHeader (ObsGPSTime 100000 1024) 4)
-                         [ PackedObsContent 222222 (CarrierPhase 22 22) 2 2 0
-                         , PackedObsContent 222222 (CarrierPhase 22 22) 2 2 1
-                         , PackedObsContent 222222 (CarrierPhase 22 22) 2 2 2
-                         , PackedObsContent 222222 (CarrierPhase 22 22) 2 2 3
-                         ]
-
-longMsgToEncode' :: SBPMsg
-longMsgToEncode' = SBPMsgObs longMsgToEncode (toSBP longMsgToEncode defaultSender)
-
-binaryToDecode :: ByteString
-binaryToDecode = Base64.decodeLenient "VRUAwwQNzcx0QQAgQ0TkSpRFDhdL"
-
-longBinaryToDecode :: ByteString
-longBinaryToDecode = Base64.decodeLenient "VUYAwwSwAAAAAAAATb4AAAAAAHpTwAAAAAAA6\
-                                          \W5AAAAAAAA8z74AAAAAABzePgAAAAAAgHg+AA\
-                                          \AAAAAAbD4K5reM1uYyPjZWxKT8Cv8/AAAAJPe\
-                                          \/gD8AAKAFwSG0QLqKUYFY7wFAXtJ4qmoZQb5n\
-                                          \1SCb48Lgv5wvaF1lN+8/xFNk/jM2BL4AAAAAM\
-                                          \vI0PwAAAAAAAHK9AAAAAAAAAAAAAAAAgAwZQS\
-                                          \4HAAAAAIAMGUEuBwEBHgCqIQ=="
-
-jsonEncode :: Benchmark
-jsonEncode = do
-  bgroup "JSON encoding"
-    [ bench "Encode short message (acq)"    $ nf A.encode msgToEncode
-    , bench "Encode wrapped message"        $ nf A.encode msgToEncode'
-    , bench "Encode longer message (obs)"   $ nf A.encode longMsgToEncode
-    , bench "Encode longer wrapped message" $ nf A.encode longMsgToEncode'
-    , bench "Encode longer message (base)"  $ nf A.encode msgToEncode1
-    , bench "Encode longer wrapped message" $ nf A.encode msgToEncode1'
-    ]
-
-binaryEncode :: Benchmark
-binaryEncode = do
-  bgroup "Binary encoding"
-    [ bench "Encode short message (acq)"    $ nf B.encode msgToEncode
-    , bench "Encode wrapped message"        $ nf B.encode msgToEncode'
-    , bench "Encode longer message (obs)"   $ nf B.encode longMsgToEncode
-    , bench "Encode longer wrapped message" $ nf B.encode longMsgToEncode'
-    , bench "Encode longer message (base)"  $ nf B.encode msgToEncode1
-    , bench "Encode longer wrapped message" $ nf B.encode msgToEncode1'
-    ]
-
-decodeSBP :: LBS.ByteString -> SBPMsg
-decodeSBP x = B.decode x
-
-binaryDecode :: Benchmark
-binaryDecode = do
-  bgroup "Binary decoding"
-    [ bench "Decode short message"  $ whnf decodeSBP (LBS.fromStrict binaryToDecode)
-    , bench "Decode longer message" $ whnf decodeSBP (LBS.fromStrict longBinaryToDecode)
-    ]
-
-main :: IO ()
-main = do
-  defaultMain [ jsonEncode
-              , binaryEncode
-              , binaryDecode
-              ]
diff --git a/main/JSON2SBP.hs b/main/JSON2SBP.hs
--- a/main/JSON2SBP.hs
+++ b/main/JSON2SBP.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+
 -- |
 -- Module:      JSON2SBP
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/main/SBP2JSON.hs b/main/SBP2JSON.hs
--- a/main/SBP2JSON.hs
+++ b/main/SBP2JSON.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+
 -- |
 -- Module:      SBP2JSON
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -12,8 +15,6 @@
 import           BasicPrelude
 import           Control.Monad.Trans.Resource
 import           Data.Aeson
-import           Data.Aeson.Encode
-import           Data.ByteString.Builder
 import qualified Data.ByteString.Lazy as BL
 import           Data.Conduit
 import           Data.Conduit.Binary
@@ -24,7 +25,7 @@
 
 -- | Encode a SBPMsg to a line of JSON.
 encodeLine :: SBPMsg -> ByteString
-encodeLine v = BL.toStrict $ toLazyByteString $ encodeToBuilder (toJSON v) <> "\n"
+encodeLine v = BL.toStrict $ encode v <> "\n"
 
 main :: IO ()
 main =
diff --git a/main/SBP2YAML.hs b/main/SBP2YAML.hs
--- a/main/SBP2YAML.hs
+++ b/main/SBP2YAML.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+
 -- |
 -- Module:      SBP2YAML
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/sbp.cabal b/sbp.cabal
--- a/sbp.cabal
+++ b/sbp.cabal
@@ -1,157 +1,138 @@
-name:                  sbp
-version:               2.2.6
-synopsis:              SwiftNav's SBP Library
-homepage:              https://github.com/swift-nav/libsbp
-license:               LGPL-3
-author:                Swift Navigation Inc.
-maintainer:            Mark Fine <dev@swiftnav.com>
-copyright:             Copyright (C) 2015 Swift Navigation, Inc.
-category:              Network
-build-type:            Simple
-cabal-version:         >= 1.10
-extra-source-files:    README.md
+name: sbp
+version: 2.2.7
+cabal-version: >=1.22
+build-type: Simple
+license: LGPL-3
+copyright: Copyright (C) 2015 Swift Navigation, Inc.
+maintainer: Mark Fine <dev@swiftnav.com>
+homepage: https://github.com/swift-nav/libsbp
+synopsis: SwiftNav's SBP Library
 description:
-  Haskell bindings for Swift Navigation Binary Protocol (SBP), a fast,
-  simple, and minimal binary protocol for communicating with Swift
-  devices. It is the native binary protocol used by the Piksi GPS
-  receiver to transmit solutions, observations, status and debugging
-  messages, as well as receive messages from the host operating
-  system, such as differential corrections and the almanac.
+    Haskell bindings for Swift Navigation Binary Protocol (SBP), a fast,
+    simple, and minimal binary protocol for communicating with Swift
+    devices. It is the native binary protocol used by the Piksi GPS
+    receiver to transmit solutions, observations, status and debugging
+    messages, as well as receive messages from the host operating
+    system, such as differential corrections and the almanac.
+category: Network
+author: Swift Navigation Inc.
+extra-source-files:
+    README.md
 
 source-repository head
-  type:                git
-  location:            git@github.com:swift-nav/libsbp.git
+    type: git
+    location: git@github.com:swift-nav/libsbp.git
 
 library
-  exposed-modules:     SwiftNav.CRC16
-                     , SwiftNav.SBP
-                     , SwiftNav.SBP.Msg
-                     , SwiftNav.SBP.Acquisition
-                     , SwiftNav.SBP.Bootload
-                     , SwiftNav.SBP.ExtEvents
-                     , SwiftNav.SBP.FileIo
-                     , SwiftNav.SBP.Flash
-                     , SwiftNav.SBP.Gnss
-                     , SwiftNav.SBP.Imu
-                     , SwiftNav.SBP.Logging
-                     , SwiftNav.SBP.Navigation
-                     , SwiftNav.SBP.Ndb
-                     , SwiftNav.SBP.Observation
-                     , SwiftNav.SBP.Piksi
-                     , SwiftNav.SBP.Settings
-                     , SwiftNav.SBP.System
-                     , SwiftNav.SBP.Tracking
-                     , SwiftNav.SBP.User
-                     , SwiftNav.SBP.Encoding
-                     , SwiftNav.SBP.Types
-  other-modules:       SwiftNav.SBP.TH
-  default-language:    Haskell2010
-  hs-source-dirs:      src
-  ghc-options:         -Wall -fno-warn-unused-imports -fno-warn-orphans
-  build-depends:       aeson
-                     , array
-                     , base >= 4.7 && < 5
-                     , base64-bytestring
-                     , basic-prelude
-                     , binary
-                     , bytestring
-                     , data-binary-ieee754
-                     , lens
-                     , monad-loops
-                     , template-haskell
-                     , text
-                     , unordered-containers
-  default-extensions:  RecordWildCards
-                       TemplateHaskell
-                       NoImplicitPrelude
-                       OverloadedStrings
+    exposed-modules:
+        SwiftNav.CRC16
+        SwiftNav.SBP
+        SwiftNav.SBP.Encoding
+    build-depends:
+        aeson >=0.9.0.1,
+        array >=0.5.1.0,
+        base >=4.8 && <5,
+        base64-bytestring >=1.0.0.1,
+        basic-prelude >=0.5.2,
+        binary >=0.7.5.0,
+        bytestring >=0.10.6.0,
+        data-binary-ieee754 >=0.4.4,
+        lens >=4.13,
+        monad-loops >=0.4.3,
+        template-haskell >=2.10.0.0,
+        text >=1.2.2.1,
+        unordered-containers >=0.2.5.1
+    default-language: Haskell2010
+    hs-source-dirs: src
+    other-modules:
+        SwiftNav.SBP.Msg
+        SwiftNav.SBP.TH
+        SwiftNav.SBP.Types
+        SwiftNav.SBP.Acquisition
+        SwiftNav.SBP.Bootload
+        SwiftNav.SBP.ExtEvents
+        SwiftNav.SBP.FileIo
+        SwiftNav.SBP.Flash
+        SwiftNav.SBP.Gnss
+        SwiftNav.SBP.Imu
+        SwiftNav.SBP.Logging
+        SwiftNav.SBP.Navigation
+        SwiftNav.SBP.Ndb
+        SwiftNav.SBP.Observation
+        SwiftNav.SBP.Piksi
+        SwiftNav.SBP.Settings
+        SwiftNav.SBP.System
+        SwiftNav.SBP.Tracking
+        SwiftNav.SBP.User
+    ghc-options: -Wall
 
 executable sbp2json
-  hs-source-dirs:      main
-  main-is:             SBP2JSON.hs
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
-  build-depends:       aeson
-                     , base
-                     , basic-prelude
-                     , binary-conduit
-                     , bytestring
-                     , conduit
-                     , conduit-combinators
-                     , conduit-extra
-                     , resourcet
-                     , sbp
-  default-language:    Haskell2010
-  default-extensions:  NoImplicitPrelude
-                       OverloadedStrings
+    main-is: SBP2JSON.hs
+    build-depends:
+        aeson >=0.9.0.1,
+        base >=4.8.2.0,
+        basic-prelude >=0.5.2,
+        binary-conduit >=1.2.3,
+        bytestring >=0.10.6.0,
+        conduit >=1.2.6.6,
+        conduit-combinators >=1.0.3.1,
+        conduit-extra >=1.1.13.1,
+        resourcet >=1.1.7.4,
+        sbp >=2.2.7
+    default-language: Haskell2010
+    hs-source-dirs: main
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
 
 executable json2sbp
-  hs-source-dirs:      main
-  main-is:             JSON2SBP.hs
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
-  build-depends:       aeson
-                     , base
-                     , basic-prelude
-                     , binary-conduit
-                     , bytestring
-                     , conduit
-                     , conduit-combinators
-                     , conduit-extra
-                     , resourcet
-                     , sbp
-  default-language:    Haskell2010
-  default-extensions:  NoImplicitPrelude
-                       OverloadedStrings
-executable sbp2yaml
-  hs-source-dirs:      main
-  main-is:             SBP2YAML.hs
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
-  build-depends:       base
-                     , basic-prelude
-                     , binary-conduit
-                     , bytestring
-                     , conduit
-                     , conduit-extra
-                     , resourcet
-                     , sbp
-                     , yaml
-  default-language:    Haskell2010
-  default-extensions:  NoImplicitPrelude
-                       OverloadedStrings
+    main-is: JSON2SBP.hs
+    build-depends:
+        aeson >=0.9.0.1,
+        base >=4.8.2.0,
+        basic-prelude >=0.5.2,
+        binary-conduit >=1.2.3,
+        bytestring >=0.10.6.0,
+        conduit >=1.2.6.6,
+        conduit-combinators >=1.0.3.1,
+        conduit-extra >=1.1.13.1,
+        resourcet >=1.1.7.4,
+        sbp >=2.2.7
+    default-language: Haskell2010
+    hs-source-dirs: main
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
 
-benchmark bench
-  type:                exitcode-stdio-1.0
-  hs-source-dirs:      bench
-  main-is:             Bench.hs
-  build-depends:       aeson
-                     , base
-                     , base64-bytestring
-                     , basic-prelude
-                     , binary
-                     , bytestring
-                     , criterion
-                     , sbp
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
-  default-language:    Haskell2010
-  default-extensions:  NoImplicitPrelude
-                       OverloadedStrings
+executable sbp2yaml
+    main-is: SBP2YAML.hs
+    build-depends:
+        base >=4.8.2.0,
+        basic-prelude >=0.5.2,
+        binary-conduit >=1.2.3,
+        bytestring >=0.10.6.0,
+        conduit >=1.2.6.6,
+        conduit-extra >=1.1.13.1,
+        resourcet >=1.1.7.4,
+        sbp >=2.2.7,
+        yaml >=0.8.17.1
+    default-language: Haskell2010
+    hs-source-dirs: main
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
 
 test-suite test
-  type:                exitcode-stdio-1.0
-  hs-source-dirs:      test
-  main-is:             Test.hs
-  other-modules:       Test.SwiftNav.CRC16
-                     , Test.SwiftNav.SBP.Encoding
-  build-depends:       aeson
-                     , base
-                     , base64-bytestring
-                     , basic-prelude
-                     , bytestring
-                     , QuickCheck
-                     , sbp
-                     , tasty
-                     , tasty-hunit
-                     , tasty-quickcheck
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
-  default-language:    Haskell2010
-  default-extensions:  NoImplicitPrelude
-                       OverloadedStrings
+    type: exitcode-stdio-1.0
+    main-is: Test.hs
+    build-depends:
+        aeson >=0.9.0.1,
+        base >=4.8.2.0,
+        base64-bytestring >=1.0.0.1,
+        basic-prelude >=0.5.2,
+        bytestring >=0.10.6.0,
+        QuickCheck >=2.8.1,
+        sbp >=2.2.7,
+        tasty >=0.11.0.3,
+        tasty-hunit >=0.9.2,
+        tasty-quickcheck >=0.8.4
+    default-language: Haskell2010
+    hs-source-dirs: test
+    other-modules:
+        Test.SwiftNav.CRC16
+        Test.SwiftNav.SBP.Encoding
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
diff --git a/src/SwiftNav/CRC16.hs b/src/SwiftNav/CRC16.hs
--- a/src/SwiftNav/CRC16.hs
+++ b/src/SwiftNav/CRC16.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+
 -- |
 -- Module:      SwiftNav.SBP
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/src/SwiftNav/SBP.hs b/src/SwiftNav/SBP.hs
--- a/src/SwiftNav/SBP.hs
+++ b/src/SwiftNav/SBP.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+
 -- |
 -- Module:      SwiftNav.SBP
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/src/SwiftNav/SBP/Acquisition.hs b/src/SwiftNav/SBP/Acquisition.hs
--- a/src/SwiftNav/SBP/Acquisition.hs
+++ b/src/SwiftNav/SBP/Acquisition.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Acquisition
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -38,13 +42,13 @@
 -- contains the parameters of the point in the acquisition search space with
 -- the best carrier-to-noise (CN/0) ratio.
 data MsgAcqResult = MsgAcqResult
-  { _msgAcqResult_cn0 :: Float
+  { _msgAcqResult_cn0 :: !Float
     -- ^ CN/0 of best point
-  , _msgAcqResult_cp :: Float
+  , _msgAcqResult_cp :: !Float
     -- ^ Code phase of best point
-  , _msgAcqResult_cf :: Float
+  , _msgAcqResult_cf :: !Float
     -- ^ Carrier frequency of best point
-  , _msgAcqResult_sid :: GnssSignal
+  , _msgAcqResult_sid :: !GnssSignal
     -- ^ GNSS signal for which acquisition was attempted
   } deriving ( Show, Read, Eq )
 
@@ -75,14 +79,14 @@
 --
 -- Deprecated.
 data MsgAcqResultDepB = MsgAcqResultDepB
-  { _msgAcqResultDepB_snr :: Float
+  { _msgAcqResultDepB_snr :: !Float
     -- ^ SNR of best point. Currently in arbitrary SNR points, but will be in
     -- units of dB Hz in a later revision of this message.
-  , _msgAcqResultDepB_cp :: Float
+  , _msgAcqResultDepB_cp :: !Float
     -- ^ Code phase of best point
-  , _msgAcqResultDepB_cf :: Float
+  , _msgAcqResultDepB_cf :: !Float
     -- ^ Carrier frequency of best point
-  , _msgAcqResultDepB_sid :: GnssSignal
+  , _msgAcqResultDepB_sid :: !GnssSignal
     -- ^ GNSS signal for which acquisition was attempted
   } deriving ( Show, Read, Eq )
 
@@ -113,14 +117,14 @@
 --
 -- Deprecated.
 data MsgAcqResultDepA = MsgAcqResultDepA
-  { _msgAcqResultDepA_snr :: Float
+  { _msgAcqResultDepA_snr :: !Float
     -- ^ SNR of best point. Currently dimensonless, but will have units of dB Hz
     -- in the revision of this message.
-  , _msgAcqResultDepA_cp :: Float
+  , _msgAcqResultDepA_cp :: !Float
     -- ^ Code phase of best point
-  , _msgAcqResultDepA_cf :: Float
+  , _msgAcqResultDepA_cf :: !Float
     -- ^ Carrier frequency of best point
-  , _msgAcqResultDepA_prn :: Word8
+  , _msgAcqResultDepA_prn :: !Word8
     -- ^ PRN-1 identifier of the satellite signal for which acquisition was
     -- attempted
   } deriving ( Show, Read, Eq )
@@ -151,29 +155,29 @@
 -- profile during acquisition time. The message is used to debug and measure
 -- the performance.
 data AcqSvProfile = AcqSvProfile
-  { _acqSvProfile_job_type :: Word8
+  { _acqSvProfile_job_type :: !Word8
     -- ^ SV search job type (deep, fallback, etc)
-  , _acqSvProfile_status   :: Word8
+  , _acqSvProfile_status   :: !Word8
     -- ^ Acquisition status 1 is Success, 0 is Failure
-  , _acqSvProfile_cn0      :: Word16
+  , _acqSvProfile_cn0      :: !Word16
     -- ^ CN0 value. Only valid if status is '1'
-  , _acqSvProfile_int_time :: Word8
+  , _acqSvProfile_int_time :: !Word8
     -- ^ Acquisition integration time
-  , _acqSvProfile_sid      :: GnssSignal
+  , _acqSvProfile_sid      :: !GnssSignal
     -- ^ GNSS signal for which acquisition was attempted
-  , _acqSvProfile_bin_width :: Word16
+  , _acqSvProfile_bin_width :: !Word16
     -- ^ Acq frequency bin width
-  , _acqSvProfile_timestamp :: Word32
+  , _acqSvProfile_timestamp :: !Word32
     -- ^ Timestamp of the job complete event
-  , _acqSvProfile_time_spent :: Word32
+  , _acqSvProfile_time_spent :: !Word32
     -- ^ Time spent to search for sid.code
-  , _acqSvProfile_cf_min   :: Int32
+  , _acqSvProfile_cf_min   :: !Int32
     -- ^ Doppler range lowest frequency
-  , _acqSvProfile_cf_max   :: Int32
+  , _acqSvProfile_cf_max   :: !Int32
     -- ^ Doppler range highest frequency
-  , _acqSvProfile_cf       :: Int32
+  , _acqSvProfile_cf       :: !Int32
     -- ^ Doppler value of detected peak. Only valid if status is '1'
-  , _acqSvProfile_cp       :: Word32
+  , _acqSvProfile_cp       :: !Word32
     -- ^ Codephase of detected peak. Only valid if status is '1'
   } deriving ( Show, Read, Eq )
 
@@ -218,7 +222,7 @@
 -- The message describes all SV profiles during acquisition time. The message
 -- is used to debug and measure the performance.
 data MsgAcqSvProfile = MsgAcqSvProfile
-  { _msgAcqSvProfile_acq_sv_profile :: [AcqSvProfile]
+  { _msgAcqSvProfile_acq_sv_profile :: ![AcqSvProfile]
     -- ^ SV profiles during acquisition time
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Bootload.hs b/src/SwiftNav/SBP/Bootload.hs
--- a/src/SwiftNav/SBP/Bootload.hs
+++ b/src/SwiftNav/SBP/Bootload.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Bootload
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -63,9 +67,9 @@
 -- MSG_BOOTLOADER_HANDSHAKE_REQ.  The payload contains the bootloader version
 -- number and the SBP protocol version number.
 data MsgBootloaderHandshakeResp = MsgBootloaderHandshakeResp
-  { _msgBootloaderHandshakeResp_flags :: Word32
+  { _msgBootloaderHandshakeResp_flags :: !Word32
     -- ^ Bootloader flags
-  , _msgBootloaderHandshakeResp_version :: Text
+  , _msgBootloaderHandshakeResp_version :: !Text
     -- ^ Bootloader version number
   } deriving ( Show, Read, Eq )
 
@@ -92,7 +96,7 @@
 --
 -- The host initiates the bootloader to jump to the application.
 data MsgBootloaderJumpToApp = MsgBootloaderJumpToApp
-  { _msgBootloaderJumpToApp_jump :: Word8
+  { _msgBootloaderJumpToApp_jump :: !Word8
     -- ^ Ignored by the device
   } deriving ( Show, Read, Eq )
 
@@ -148,7 +152,7 @@
 -- that this ID is tied to the FPGA, and not related to the Piksi's serial
 -- number.
 data MsgNapDeviceDnaResp = MsgNapDeviceDnaResp
-  { _msgNapDeviceDnaResp_dna :: [Word8]
+  { _msgNapDeviceDnaResp_dna :: ![Word8]
     -- ^ 57-bit SwiftNAP FPGA Device ID. Remaining bits are padded on the right.
   } deriving ( Show, Read, Eq )
 
@@ -173,7 +177,7 @@
 --
 -- Deprecated.
 data MsgBootloaderHandshakeDepA = MsgBootloaderHandshakeDepA
-  { _msgBootloaderHandshakeDepA_handshake :: [Word8]
+  { _msgBootloaderHandshakeDepA_handshake :: ![Word8]
     -- ^ Version number string (not NULL terminated)
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Encoding.hs b/src/SwiftNav/SBP/Encoding.hs
--- a/src/SwiftNav/SBP/Encoding.hs
+++ b/src/SwiftNav/SBP/Encoding.hs
@@ -1,4 +1,6 @@
-{-# OPTIONS -fno-warn-orphans #-}
+{-# OPTIONS -fno-warn-orphans  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Encoding
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/src/SwiftNav/SBP/ExtEvents.hs b/src/SwiftNav/SBP/ExtEvents.hs
--- a/src/SwiftNav/SBP/ExtEvents.hs
+++ b/src/SwiftNav/SBP/ExtEvents.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.ExtEvents
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -36,16 +40,16 @@
 -- Reports detection of an external event, the GPS time it occurred, which pin
 -- it was and whether it was rising or falling.
 data MsgExtEvent = MsgExtEvent
-  { _msgExtEvent_wn        :: Word16
+  { _msgExtEvent_wn        :: !Word16
     -- ^ GPS week number
-  , _msgExtEvent_tow       :: Word32
+  , _msgExtEvent_tow       :: !Word32
     -- ^ GPS time of week rounded to the nearest millisecond
-  , _msgExtEvent_ns_residual :: Int32
+  , _msgExtEvent_ns_residual :: !Int32
     -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
     -- 500000)
-  , _msgExtEvent_flags     :: Word8
+  , _msgExtEvent_flags     :: !Word8
     -- ^ Flags
-  , _msgExtEvent_pin       :: Word8
+  , _msgExtEvent_pin       :: !Word8
     -- ^ Pin number.  0..9 = DEBUG0..9.
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/FileIo.hs b/src/SwiftNav/SBP/FileIo.hs
--- a/src/SwiftNav/SBP/FileIo.hs
+++ b/src/SwiftNav/SBP/FileIo.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.FileIo
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -45,13 +49,13 @@
 -- fileio read message". A device will only respond to this message when it is
 -- received from sender ID 0x42.
 data MsgFileioReadReq = MsgFileioReadReq
-  { _msgFileioReadReq_sequence :: Word32
+  { _msgFileioReadReq_sequence :: !Word32
     -- ^ Read sequence number
-  , _msgFileioReadReq_offset   :: Word32
+  , _msgFileioReadReq_offset   :: !Word32
     -- ^ File offset
-  , _msgFileioReadReq_chunk_size :: Word8
+  , _msgFileioReadReq_chunk_size :: !Word8
     -- ^ Chunk size to read
-  , _msgFileioReadReq_filename :: Text
+  , _msgFileioReadReq_filename :: !Text
     -- ^ Name of the file to read from
   } deriving ( Show, Read, Eq )
 
@@ -85,9 +89,9 @@
 -- length field indicates how many bytes were succesfully read. The sequence
 -- number in the response is preserved from the request.
 data MsgFileioReadResp = MsgFileioReadResp
-  { _msgFileioReadResp_sequence :: Word32
+  { _msgFileioReadResp_sequence :: !Word32
     -- ^ Read sequence number
-  , _msgFileioReadResp_contents :: [Word8]
+  , _msgFileioReadResp_contents :: ![Word8]
     -- ^ Contents of read file
   } deriving ( Show, Read, Eq )
 
@@ -121,11 +125,11 @@
 -- MSG_PRINT message will print "Invalid fileio read message". A device will
 -- only respond to this message when it is received from sender ID 0x42.
 data MsgFileioReadDirReq = MsgFileioReadDirReq
-  { _msgFileioReadDirReq_sequence :: Word32
+  { _msgFileioReadDirReq_sequence :: !Word32
     -- ^ Read sequence number
-  , _msgFileioReadDirReq_offset :: Word32
+  , _msgFileioReadDirReq_offset :: !Word32
     -- ^ The offset to skip the first n elements of the file list
-  , _msgFileioReadDirReq_dirname :: Text
+  , _msgFileioReadDirReq_dirname :: !Text
     -- ^ Name of the directory to list
   } deriving ( Show, Read, Eq )
 
@@ -158,9 +162,9 @@
 -- of the list is identified by an entry containing just the character 0xFF.
 -- The sequence number in the response is preserved from the request.
 data MsgFileioReadDirResp = MsgFileioReadDirResp
-  { _msgFileioReadDirResp_sequence :: Word32
+  { _msgFileioReadDirResp_sequence :: !Word32
     -- ^ Read sequence number
-  , _msgFileioReadDirResp_contents :: [Word8]
+  , _msgFileioReadDirResp_contents :: ![Word8]
     -- ^ Contents of read directory
   } deriving ( Show, Read, Eq )
 
@@ -190,7 +194,7 @@
 -- message". A device will only process this message when it is received from
 -- sender ID 0x42.
 data MsgFileioRemove = MsgFileioRemove
-  { _msgFileioRemove_filename :: Text
+  { _msgFileioRemove_filename :: !Text
     -- ^ Name of the file to delete
   } deriving ( Show, Read, Eq )
 
@@ -221,13 +225,13 @@
 -- message". A device will only  process this message when it is received from
 -- sender ID 0x42.
 data MsgFileioWriteReq = MsgFileioWriteReq
-  { _msgFileioWriteReq_sequence :: Word32
+  { _msgFileioWriteReq_sequence :: !Word32
     -- ^ Write sequence number
-  , _msgFileioWriteReq_offset :: Word32
+  , _msgFileioWriteReq_offset :: !Word32
     -- ^ Offset into the file at which to start writing in bytes
-  , _msgFileioWriteReq_filename :: Text
+  , _msgFileioWriteReq_filename :: !Text
     -- ^ Name of the file to write to
-  , _msgFileioWriteReq_data   :: [Word8]
+  , _msgFileioWriteReq_data   :: ![Word8]
     -- ^ Variable-length array of data to write
   } deriving ( Show, Read, Eq )
 
@@ -261,7 +265,7 @@
 -- MSG_FILEIO_WRITE_REQ message to check integrity of the write. The sequence
 -- number in the response is preserved from the request.
 data MsgFileioWriteResp = MsgFileioWriteResp
-  { _msgFileioWriteResp_sequence :: Word32
+  { _msgFileioWriteResp_sequence :: !Word32
     -- ^ Write sequence number
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Flash.hs b/src/SwiftNav/SBP/Flash.hs
--- a/src/SwiftNav/SBP/Flash.hs
+++ b/src/SwiftNav/SBP/Flash.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Flash
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -41,13 +45,13 @@
 -- if the maximum write size is exceeded. Note that the sector-containing
 -- addresses must be erased before addresses can be programmed.
 data MsgFlashProgram = MsgFlashProgram
-  { _msgFlashProgram_target   :: Word8
+  { _msgFlashProgram_target   :: !Word8
     -- ^ Target flags
-  , _msgFlashProgram_addr_start :: [Word8]
+  , _msgFlashProgram_addr_start :: ![Word8]
     -- ^ Starting address offset to program
-  , _msgFlashProgram_addr_len :: Word8
+  , _msgFlashProgram_addr_len :: !Word8
     -- ^ Length of set of addresses to program, counting up from starting address
-  , _msgFlashProgram_data     :: [Word8]
+  , _msgFlashProgram_data     :: ![Word8]
     -- ^ Data to program addresses with, with length N=addr_len
   } deriving ( Show, Read, Eq )
 
@@ -81,7 +85,7 @@
 -- MSG_FLASH_READ_REQ, or MSG_FLASH_PROGRAM, may return this message on
 -- failure.
 data MsgFlashDone = MsgFlashDone
-  { _msgFlashDone_response :: Word8
+  { _msgFlashDone_response :: !Word8
     -- ^ Response flags
   } deriving ( Show, Read, Eq )
 
@@ -111,11 +115,11 @@
 -- exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the allowed
 -- range.
 data MsgFlashReadReq = MsgFlashReadReq
-  { _msgFlashReadReq_target   :: Word8
+  { _msgFlashReadReq_target   :: !Word8
     -- ^ Target flags
-  , _msgFlashReadReq_addr_start :: [Word8]
+  , _msgFlashReadReq_addr_start :: ![Word8]
     -- ^ Starting address offset to read from
-  , _msgFlashReadReq_addr_len :: Word8
+  , _msgFlashReadReq_addr_len :: !Word8
     -- ^ Length of set of addresses to read, counting up from starting address
   } deriving ( Show, Read, Eq )
 
@@ -149,11 +153,11 @@
 -- exceeded or FLASH_INVALID_ADDR (3) if the address is outside of the allowed
 -- range.
 data MsgFlashReadResp = MsgFlashReadResp
-  { _msgFlashReadResp_target   :: Word8
+  { _msgFlashReadResp_target   :: !Word8
     -- ^ Target flags
-  , _msgFlashReadResp_addr_start :: [Word8]
+  , _msgFlashReadResp_addr_start :: ![Word8]
     -- ^ Starting address offset to read from
-  , _msgFlashReadResp_addr_len :: Word8
+  , _msgFlashReadResp_addr_len :: !Word8
     -- ^ Length of set of addresses to read, counting up from starting address
   } deriving ( Show, Read, Eq )
 
@@ -185,9 +189,9 @@
 -- message containing the return code - FLASH_OK (0) on success or
 -- FLASH_INVALID_FLASH (1) if the flash specified is invalid.
 data MsgFlashErase = MsgFlashErase
-  { _msgFlashErase_target   :: Word8
+  { _msgFlashErase_target   :: !Word8
     -- ^ Target flags
-  , _msgFlashErase_sector_num :: Word32
+  , _msgFlashErase_sector_num :: !Word32
     -- ^ Flash sector number to erase (0-11 for the STM, 0-15 for the M25)
   } deriving ( Show, Read, Eq )
 
@@ -215,7 +219,7 @@
 -- The flash lock message locks a sector of the STM flash memory. The device
 -- replies with a MSG_FLASH_DONE message.
 data MsgStmFlashLockSector = MsgStmFlashLockSector
-  { _msgStmFlashLockSector_sector :: Word32
+  { _msgStmFlashLockSector_sector :: !Word32
     -- ^ Flash sector number to lock
   } deriving ( Show, Read, Eq )
 
@@ -241,7 +245,7 @@
 -- The flash unlock message unlocks a sector of the STM flash memory. The
 -- device replies with a MSG_FLASH_DONE message.
 data MsgStmFlashUnlockSector = MsgStmFlashUnlockSector
-  { _msgStmFlashUnlockSector_sector :: Word32
+  { _msgStmFlashUnlockSector_sector :: !Word32
     -- ^ Flash sector number to unlock
   } deriving ( Show, Read, Eq )
 
@@ -292,7 +296,7 @@
 -- ID by sending a MSG_STM_UNIQUE_ID_REQ. The device responds with a
 -- MSG_STM_UNIQUE_ID_RESP with the 12-byte unique ID in the payload..
 data MsgStmUniqueIdResp = MsgStmUniqueIdResp
-  { _msgStmUniqueIdResp_stm_id :: [Word8]
+  { _msgStmUniqueIdResp_stm_id :: ![Word8]
     -- ^ Device unique ID
   } deriving ( Show, Read, Eq )
 
@@ -318,7 +322,7 @@
 -- The flash status message writes to the 8-bit M25 flash status register. The
 -- device replies with a MSG_FLASH_DONE message.
 data MsgM25FlashWriteStatus = MsgM25FlashWriteStatus
-  { _msgM25FlashWriteStatus_status :: [Word8]
+  { _msgM25FlashWriteStatus_status :: ![Word8]
     -- ^ Byte to write to the M25 flash status register
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Gnss.hs b/src/SwiftNav/SBP/Gnss.hs
--- a/src/SwiftNav/SBP/Gnss.hs
+++ b/src/SwiftNav/SBP/Gnss.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Gnss
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -31,9 +35,9 @@
 --
 -- Signal identifier containing constellation, band, and satellite identifier
 data GnssSignal16 = GnssSignal16
-  { _gnssSignal16_sat :: Word8
+  { _gnssSignal16_sat :: !Word8
     -- ^ Constellation-specific satellite identifier
-  , _gnssSignal16_code :: Word8
+  , _gnssSignal16_code :: !Word8
     -- ^ Signal constellation, band and code
   } deriving ( Show, Read, Eq )
 
@@ -54,13 +58,13 @@
 --
 -- Signal identifier containing constellation, band, and satellite identifier
 data GnssSignal = GnssSignal
-  { _gnssSignal_sat    :: Word16
+  { _gnssSignal_sat    :: !Word16
     -- ^ Constellation-specific satellite identifier.  Note: unlike GnssSignal16,
     -- GPS satellites are encoded as (PRN - 1). Other constellations do not
     -- have this offset.
-  , _gnssSignal_code   :: Word8
+  , _gnssSignal_code   :: !Word8
     -- ^ Signal constellation, band and code
-  , _gnssSignal_reserved :: Word8
+  , _gnssSignal_reserved :: !Word8
     -- ^ Reserved
   } deriving ( Show, Read, Eq )
 
@@ -84,9 +88,9 @@
 -- A wire-appropriate GPS time, defined as the number of milliseconds since
 -- beginning of the week on the Saturday/Sunday transition.
 data GpsTime = GpsTime
-  { _gpsTime_tow :: Word32
+  { _gpsTime_tow :: !Word32
     -- ^ Milliseconds since start of GPS week
-  , _gpsTime_wn :: Word16
+  , _gpsTime_wn :: !Word16
     -- ^ GPS week number
   } deriving ( Show, Read, Eq )
 
@@ -108,9 +112,9 @@
 -- A GPS time, defined as the number of seconds since beginning of the week on
 -- the Saturday/Sunday transition.
 data GpsTimeSec = GpsTimeSec
-  { _gpsTimeSec_tow :: Word32
+  { _gpsTimeSec_tow :: !Word32
     -- ^ Seconds since start of GPS week
-  , _gpsTimeSec_wn :: Word16
+  , _gpsTimeSec_wn :: !Word16
     -- ^ GPS week number
   } deriving ( Show, Read, Eq )
 
@@ -133,12 +137,12 @@
 -- beginning of the week on the Saturday/Sunday transition. In most cases,
 -- observations are epoch aligned so ns field will be 0.
 data GpsTimeNano = GpsTimeNano
-  { _gpsTimeNano_tow       :: Word32
+  { _gpsTimeNano_tow       :: !Word32
     -- ^ Milliseconds since start of GPS week
-  , _gpsTimeNano_ns_residual :: Int32
+  , _gpsTimeNano_ns_residual :: !Int32
     -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
     -- 500000)
-  , _gpsTimeNano_wn        :: Word16
+  , _gpsTimeNano_wn        :: !Word16
     -- ^ GPS week number
   } deriving ( Show, Read, Eq )
 
@@ -163,9 +167,9 @@
 -- number with Q32.8 layout, i.e. 32-bits of whole cycles and 8-bits of
 -- fractional cycles. This phase has the same sign as the pseudorange.
 data CarrierPhase = CarrierPhase
-  { _carrierPhase_i :: Int32
+  { _carrierPhase_i :: !Int32
     -- ^ Carrier phase whole cycles
-  , _carrierPhase_f :: Word8
+  , _carrierPhase_f :: !Word8
     -- ^ Carrier phase fractional part
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Imu.hs b/src/SwiftNav/SBP/Imu.hs
--- a/src/SwiftNav/SBP/Imu.hs
+++ b/src/SwiftNav/SBP/Imu.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Imu
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -35,22 +39,22 @@
 -- Raw data from the Inertial Measurement Unit, containing accelerometer and
 -- gyroscope readings.
 data MsgImuRaw = MsgImuRaw
-  { _msgImuRaw_tow :: Word32
+  { _msgImuRaw_tow :: !Word32
     -- ^ Milliseconds since start of GPS week. If the high bit is set, the time
     -- is unknown or invalid.
-  , _msgImuRaw_tow_f :: Word8
+  , _msgImuRaw_tow_f :: !Word8
     -- ^ Milliseconds since start of GPS week, fractional part
-  , _msgImuRaw_acc_x :: Int16
+  , _msgImuRaw_acc_x :: !Int16
     -- ^ Acceleration in the body frame X axis
-  , _msgImuRaw_acc_y :: Int16
+  , _msgImuRaw_acc_y :: !Int16
     -- ^ Acceleration in the body frame Y axis
-  , _msgImuRaw_acc_z :: Int16
+  , _msgImuRaw_acc_z :: !Int16
     -- ^ Acceleration in the body frame Z axis
-  , _msgImuRaw_gyr_x :: Int16
+  , _msgImuRaw_gyr_x :: !Int16
     -- ^ Angular rate around the body frame X axis
-  , _msgImuRaw_gyr_y :: Int16
+  , _msgImuRaw_gyr_y :: !Int16
     -- ^ Angular rate around the body frame Y axis
-  , _msgImuRaw_gyr_z :: Int16
+  , _msgImuRaw_gyr_z :: !Int16
     -- ^ Angular rate around the body frame Z axis
   } deriving ( Show, Read, Eq )
 
@@ -91,11 +95,11 @@
 -- always be consistent but the rest of the payload is device specific and
 -- depends on the value of `imu_type`.
 data MsgImuAux = MsgImuAux
-  { _msgImuAux_imu_type :: Word8
+  { _msgImuAux_imu_type :: !Word8
     -- ^ IMU type
-  , _msgImuAux_temp   :: Int16
+  , _msgImuAux_temp   :: !Int16
     -- ^ Raw IMU temperature
-  , _msgImuAux_imu_conf :: Word8
+  , _msgImuAux_imu_conf :: !Word8
     -- ^ IMU configuration
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Logging.hs b/src/SwiftNav/SBP/Logging.hs
--- a/src/SwiftNav/SBP/Logging.hs
+++ b/src/SwiftNav/SBP/Logging.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Logging
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -36,9 +40,9 @@
 -- containing errors, warnings and informational messages at ERROR, WARNING,
 -- DEBUG, INFO logging levels.
 data MsgLog = MsgLog
-  { _msgLog_level :: Word8
+  { _msgLog_level :: !Word8
     -- ^ Logging level
-  , _msgLog_text :: Text
+  , _msgLog_text :: !Text
     -- ^ Human-readable string
   } deriving ( Show, Read, Eq )
 
@@ -71,11 +75,11 @@
 -- Protocol 0 represents SBP and the remaining values are implementation
 -- defined.
 data MsgFwd = MsgFwd
-  { _msgFwd_source    :: Word8
+  { _msgFwd_source    :: !Word8
     -- ^ source identifier
-  , _msgFwd_protocol  :: Word8
+  , _msgFwd_protocol  :: !Word8
     -- ^ protocol identifier
-  , _msgFwd_fwd_payload :: Text
+  , _msgFwd_fwd_payload :: !Text
     -- ^ variable length wrapped binary message
   } deriving ( Show, Read, Eq )
 
@@ -104,7 +108,7 @@
 --
 -- All the news fit to tweet.
 data MsgTweet = MsgTweet
-  { _msgTweet_tweet :: Text
+  { _msgTweet_tweet :: !Text
     -- ^ Human-readable string
   } deriving ( Show, Read, Eq )
 
@@ -129,7 +133,7 @@
 --
 -- Deprecated.
 data MsgPrintDep = MsgPrintDep
-  { _msgPrintDep_text :: Text
+  { _msgPrintDep_text :: !Text
     -- ^ Human-readable string
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Msg.hs b/src/SwiftNav/SBP/Msg.hs
--- a/src/SwiftNav/SBP/Msg.hs
+++ b/src/SwiftNav/SBP/Msg.hs
@@ -1,3 +1,9 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+{-# LANGUAGE OverloadedStrings           #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Msg
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/src/SwiftNav/SBP/Navigation.hs b/src/SwiftNav/SBP/Navigation.hs
--- a/src/SwiftNav/SBP/Navigation.hs
+++ b/src/SwiftNav/SBP/Navigation.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Navigation
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -50,14 +54,14 @@
 -- other navigation messages referenced to the same time (but lacking the ns
 -- field) and indicates a more precise time of these messages.
 data MsgGpsTime = MsgGpsTime
-  { _msgGpsTime_wn        :: Word16
+  { _msgGpsTime_wn        :: !Word16
     -- ^ GPS week number
-  , _msgGpsTime_tow       :: Word32
+  , _msgGpsTime_tow       :: !Word32
     -- ^ GPS time of week rounded to the nearest millisecond
-  , _msgGpsTime_ns_residual :: Int32
+  , _msgGpsTime_ns_residual :: !Int32
     -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
     -- 500000)
-  , _msgGpsTime_flags     :: Word8
+  , _msgGpsTime_flags     :: !Word8
     -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
@@ -90,23 +94,23 @@
 -- which indicate the source of the UTC offset value and source of the time
 -- fix.
 data MsgUtcTime = MsgUtcTime
-  { _msgUtcTime_flags :: Word8
+  { _msgUtcTime_flags :: !Word8
     -- ^ Indicates source and time validity
-  , _msgUtcTime_tow   :: Word32
+  , _msgUtcTime_tow   :: !Word32
     -- ^ GPS time of week rounded to the nearest millisecond
-  , _msgUtcTime_year  :: Word16
+  , _msgUtcTime_year  :: !Word16
     -- ^ Year
-  , _msgUtcTime_month :: Word8
+  , _msgUtcTime_month :: !Word8
     -- ^ Month (range 1 .. 12)
-  , _msgUtcTime_day   :: Word8
+  , _msgUtcTime_day   :: !Word8
     -- ^ days in the month (range 1-31)
-  , _msgUtcTime_hours :: Word8
+  , _msgUtcTime_hours :: !Word8
     -- ^ hours of day (range 0-23)
-  , _msgUtcTime_minutes :: Word8
+  , _msgUtcTime_minutes :: !Word8
     -- ^ minutes of hour (range 0-59)
-  , _msgUtcTime_seconds :: Word8
+  , _msgUtcTime_seconds :: !Word8
     -- ^ seconds of minute (range 0-60) rounded down
-  , _msgUtcTime_ns    :: Word32
+  , _msgUtcTime_ns    :: !Word32
     -- ^ nanoseconds of second (range 0-999999999)
   } deriving ( Show, Read, Eq )
 
@@ -150,19 +154,19 @@
 -- indicated whether the DOP reported corresponds to differential or SPP
 -- solution.
 data MsgDops = MsgDops
-  { _msgDops_tow :: Word32
+  { _msgDops_tow :: !Word32
     -- ^ GPS Time of Week
-  , _msgDops_gdop :: Word16
+  , _msgDops_gdop :: !Word16
     -- ^ Geometric Dilution of Precision
-  , _msgDops_pdop :: Word16
+  , _msgDops_pdop :: !Word16
     -- ^ Position Dilution of Precision
-  , _msgDops_tdop :: Word16
+  , _msgDops_tdop :: !Word16
     -- ^ Time Dilution of Precision
-  , _msgDops_hdop :: Word16
+  , _msgDops_hdop :: !Word16
     -- ^ Horizontal Dilution of Precision
-  , _msgDops_vdop :: Word16
+  , _msgDops_vdop :: !Word16
     -- ^ Vertical Dilution of Precision
-  , _msgDops_flags :: Word8
+  , _msgDops_flags :: !Word8
     -- ^ Indicates the position solution with which the DOPS message corresponds
   } deriving ( Show, Read, Eq )
 
@@ -205,19 +209,19 @@
 -- baseline vector. The full GPS time is given by the preceding MSG_GPS_TIME
 -- with the matching time-of-week (tow).
 data MsgPosEcef = MsgPosEcef
-  { _msgPosEcef_tow    :: Word32
+  { _msgPosEcef_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgPosEcef_x      :: Double
+  , _msgPosEcef_x      :: !Double
     -- ^ ECEF X coordinate
-  , _msgPosEcef_y      :: Double
+  , _msgPosEcef_y      :: !Double
     -- ^ ECEF Y coordinate
-  , _msgPosEcef_z      :: Double
+  , _msgPosEcef_z      :: !Double
     -- ^ ECEF Z coordinate
-  , _msgPosEcef_accuracy :: Word16
+  , _msgPosEcef_accuracy :: !Word16
     -- ^ Position accuracy estimate.
-  , _msgPosEcef_n_sats :: Word8
+  , _msgPosEcef_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgPosEcef_flags  :: Word8
+  , _msgPosEcef_flags  :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -260,21 +264,21 @@
 -- time is given by the preceding MSG_GPS_TIME with the matching time-of-week
 -- (tow).
 data MsgPosLlh = MsgPosLlh
-  { _msgPosLlh_tow      :: Word32
+  { _msgPosLlh_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgPosLlh_lat      :: Double
+  , _msgPosLlh_lat      :: !Double
     -- ^ Latitude
-  , _msgPosLlh_lon      :: Double
+  , _msgPosLlh_lon      :: !Double
     -- ^ Longitude
-  , _msgPosLlh_height   :: Double
+  , _msgPosLlh_height   :: !Double
     -- ^ Height above WGS84 ellipsoid
-  , _msgPosLlh_h_accuracy :: Word16
+  , _msgPosLlh_h_accuracy :: !Word16
     -- ^ Horizontal position accuracy estimate.
-  , _msgPosLlh_v_accuracy :: Word16
+  , _msgPosLlh_v_accuracy :: !Word16
     -- ^ Vertical position accuracy estimate.
-  , _msgPosLlh_n_sats   :: Word8
+  , _msgPosLlh_n_sats   :: !Word8
     -- ^ Number of satellites used in solution.
-  , _msgPosLlh_flags    :: Word8
+  , _msgPosLlh_flags    :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -316,19 +320,19 @@
 -- base station to the rover receiver. The full GPS time is given by the
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgBaselineEcef = MsgBaselineEcef
-  { _msgBaselineEcef_tow    :: Word32
+  { _msgBaselineEcef_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineEcef_x      :: Int32
+  , _msgBaselineEcef_x      :: !Int32
     -- ^ Baseline ECEF X coordinate
-  , _msgBaselineEcef_y      :: Int32
+  , _msgBaselineEcef_y      :: !Int32
     -- ^ Baseline ECEF Y coordinate
-  , _msgBaselineEcef_z      :: Int32
+  , _msgBaselineEcef_z      :: !Int32
     -- ^ Baseline ECEF Z coordinate
-  , _msgBaselineEcef_accuracy :: Word16
+  , _msgBaselineEcef_accuracy :: !Word16
     -- ^ Position accuracy estimate
-  , _msgBaselineEcef_n_sats :: Word8
+  , _msgBaselineEcef_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineEcef_flags  :: Word8
+  , _msgBaselineEcef_flags  :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -370,21 +374,21 @@
 -- GPS time is given by the preceding MSG_GPS_TIME with the matching time-of-
 -- week (tow).
 data MsgBaselineNed = MsgBaselineNed
-  { _msgBaselineNed_tow      :: Word32
+  { _msgBaselineNed_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineNed_n        :: Int32
+  , _msgBaselineNed_n        :: !Int32
     -- ^ Baseline North coordinate
-  , _msgBaselineNed_e        :: Int32
+  , _msgBaselineNed_e        :: !Int32
     -- ^ Baseline East coordinate
-  , _msgBaselineNed_d        :: Int32
+  , _msgBaselineNed_d        :: !Int32
     -- ^ Baseline Down coordinate
-  , _msgBaselineNed_h_accuracy :: Word16
+  , _msgBaselineNed_h_accuracy :: !Word16
     -- ^ Horizontal position accuracy estimate
-  , _msgBaselineNed_v_accuracy :: Word16
+  , _msgBaselineNed_v_accuracy :: !Word16
     -- ^ Vertical position accuracy estimate
-  , _msgBaselineNed_n_sats   :: Word8
+  , _msgBaselineNed_n_sats   :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineNed_flags    :: Word8
+  , _msgBaselineNed_flags    :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -425,19 +429,19 @@
 -- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
 -- the matching time-of-week (tow).
 data MsgVelEcef = MsgVelEcef
-  { _msgVelEcef_tow    :: Word32
+  { _msgVelEcef_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgVelEcef_x      :: Int32
+  , _msgVelEcef_x      :: !Int32
     -- ^ Velocity ECEF X coordinate
-  , _msgVelEcef_y      :: Int32
+  , _msgVelEcef_y      :: !Int32
     -- ^ Velocity ECEF Y coordinate
-  , _msgVelEcef_z      :: Int32
+  , _msgVelEcef_z      :: !Int32
     -- ^ Velocity ECEF Z coordinate
-  , _msgVelEcef_accuracy :: Word16
+  , _msgVelEcef_accuracy :: !Word16
     -- ^ Velocity accuracy estimate
-  , _msgVelEcef_n_sats :: Word8
+  , _msgVelEcef_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgVelEcef_flags  :: Word8
+  , _msgVelEcef_flags  :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -477,21 +481,21 @@
 -- plane centered at the current position. The full GPS time is given by the
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgVelNed = MsgVelNed
-  { _msgVelNed_tow      :: Word32
+  { _msgVelNed_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgVelNed_n        :: Int32
+  , _msgVelNed_n        :: !Int32
     -- ^ Velocity North coordinate
-  , _msgVelNed_e        :: Int32
+  , _msgVelNed_e        :: !Int32
     -- ^ Velocity East coordinate
-  , _msgVelNed_d        :: Int32
+  , _msgVelNed_d        :: !Int32
     -- ^ Velocity Down coordinate
-  , _msgVelNed_h_accuracy :: Word16
+  , _msgVelNed_h_accuracy :: !Word16
     -- ^ Horizontal velocity accuracy estimate
-  , _msgVelNed_v_accuracy :: Word16
+  , _msgVelNed_v_accuracy :: !Word16
     -- ^ Vertical velocity accuracy estimate
-  , _msgVelNed_n_sats   :: Word8
+  , _msgVelNed_n_sats   :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgVelNed_flags    :: Word8
+  , _msgVelNed_flags    :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -533,13 +537,13 @@
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow). It is intended
 -- that time-matched RTK mode is used when the base station is moving.
 data MsgBaselineHeading = MsgBaselineHeading
-  { _msgBaselineHeading_tow   :: Word32
+  { _msgBaselineHeading_tow   :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineHeading_heading :: Word32
+  , _msgBaselineHeading_heading :: !Word32
     -- ^ Heading
-  , _msgBaselineHeading_n_sats :: Word8
+  , _msgBaselineHeading_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineHeading_flags :: Word8
+  , _msgBaselineHeading_flags :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -571,9 +575,9 @@
 -- This message reports the Age of the corrections used for the current
 -- Differential solution
 data MsgAgeCorrections = MsgAgeCorrections
-  { _msgAgeCorrections_tow :: Word32
+  { _msgAgeCorrections_tow :: !Word32
     -- ^ GPS Time of Week
-  , _msgAgeCorrections_age :: Word16
+  , _msgAgeCorrections_age :: !Word16
     -- ^ Age of the corrections (0xFFFF indicates invalid)
   } deriving ( Show, Read, Eq )
 
@@ -608,14 +612,14 @@
 -- other navigation messages referenced to the same time (but lacking the ns
 -- field) and indicates a more precise time of these messages.
 data MsgGpsTimeDepA = MsgGpsTimeDepA
-  { _msgGpsTimeDepA_wn        :: Word16
+  { _msgGpsTimeDepA_wn        :: !Word16
     -- ^ GPS week number
-  , _msgGpsTimeDepA_tow       :: Word32
+  , _msgGpsTimeDepA_tow       :: !Word32
     -- ^ GPS time of week rounded to the nearest millisecond
-  , _msgGpsTimeDepA_ns_residual :: Int32
+  , _msgGpsTimeDepA_ns_residual :: !Int32
     -- ^ Nanosecond residual of millisecond-rounded TOW (ranges from -500000 to
     -- 500000)
-  , _msgGpsTimeDepA_flags     :: Word8
+  , _msgGpsTimeDepA_flags     :: !Word8
     -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
@@ -647,17 +651,17 @@
 -- This dilution of precision (DOP) message describes the effect of navigation
 -- satellite geometry on positional measurement precision.
 data MsgDopsDepA = MsgDopsDepA
-  { _msgDopsDepA_tow :: Word32
+  { _msgDopsDepA_tow :: !Word32
     -- ^ GPS Time of Week
-  , _msgDopsDepA_gdop :: Word16
+  , _msgDopsDepA_gdop :: !Word16
     -- ^ Geometric Dilution of Precision
-  , _msgDopsDepA_pdop :: Word16
+  , _msgDopsDepA_pdop :: !Word16
     -- ^ Position Dilution of Precision
-  , _msgDopsDepA_tdop :: Word16
+  , _msgDopsDepA_tdop :: !Word16
     -- ^ Time Dilution of Precision
-  , _msgDopsDepA_hdop :: Word16
+  , _msgDopsDepA_hdop :: !Word16
     -- ^ Horizontal Dilution of Precision
-  , _msgDopsDepA_vdop :: Word16
+  , _msgDopsDepA_vdop :: !Word16
     -- ^ Vertical Dilution of Precision
   } deriving ( Show, Read, Eq )
 
@@ -698,19 +702,19 @@
 -- baseline vector. The full GPS time is given by the preceding MSG_GPS_TIME
 -- with the matching time-of-week (tow).
 data MsgPosEcefDepA = MsgPosEcefDepA
-  { _msgPosEcefDepA_tow    :: Word32
+  { _msgPosEcefDepA_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgPosEcefDepA_x      :: Double
+  , _msgPosEcefDepA_x      :: !Double
     -- ^ ECEF X coordinate
-  , _msgPosEcefDepA_y      :: Double
+  , _msgPosEcefDepA_y      :: !Double
     -- ^ ECEF Y coordinate
-  , _msgPosEcefDepA_z      :: Double
+  , _msgPosEcefDepA_z      :: !Double
     -- ^ ECEF Z coordinate
-  , _msgPosEcefDepA_accuracy :: Word16
+  , _msgPosEcefDepA_accuracy :: !Word16
     -- ^ Position accuracy estimate (not implemented). Defaults to 0.
-  , _msgPosEcefDepA_n_sats :: Word8
+  , _msgPosEcefDepA_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgPosEcefDepA_flags  :: Word8
+  , _msgPosEcefDepA_flags  :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -753,21 +757,21 @@
 -- time is given by the preceding MSG_GPS_TIME with the matching time-of-week
 -- (tow).
 data MsgPosLlhDepA = MsgPosLlhDepA
-  { _msgPosLlhDepA_tow      :: Word32
+  { _msgPosLlhDepA_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgPosLlhDepA_lat      :: Double
+  , _msgPosLlhDepA_lat      :: !Double
     -- ^ Latitude
-  , _msgPosLlhDepA_lon      :: Double
+  , _msgPosLlhDepA_lon      :: !Double
     -- ^ Longitude
-  , _msgPosLlhDepA_height   :: Double
+  , _msgPosLlhDepA_height   :: !Double
     -- ^ Height
-  , _msgPosLlhDepA_h_accuracy :: Word16
+  , _msgPosLlhDepA_h_accuracy :: !Word16
     -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
-  , _msgPosLlhDepA_v_accuracy :: Word16
+  , _msgPosLlhDepA_v_accuracy :: !Word16
     -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
-  , _msgPosLlhDepA_n_sats   :: Word8
+  , _msgPosLlhDepA_n_sats   :: !Word8
     -- ^ Number of satellites used in solution.
-  , _msgPosLlhDepA_flags    :: Word8
+  , _msgPosLlhDepA_flags    :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -809,19 +813,19 @@
 -- base station to the rover receiver. The full GPS time is given by the
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgBaselineEcefDepA = MsgBaselineEcefDepA
-  { _msgBaselineEcefDepA_tow    :: Word32
+  { _msgBaselineEcefDepA_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineEcefDepA_x      :: Int32
+  , _msgBaselineEcefDepA_x      :: !Int32
     -- ^ Baseline ECEF X coordinate
-  , _msgBaselineEcefDepA_y      :: Int32
+  , _msgBaselineEcefDepA_y      :: !Int32
     -- ^ Baseline ECEF Y coordinate
-  , _msgBaselineEcefDepA_z      :: Int32
+  , _msgBaselineEcefDepA_z      :: !Int32
     -- ^ Baseline ECEF Z coordinate
-  , _msgBaselineEcefDepA_accuracy :: Word16
+  , _msgBaselineEcefDepA_accuracy :: !Word16
     -- ^ Position accuracy estimate
-  , _msgBaselineEcefDepA_n_sats :: Word8
+  , _msgBaselineEcefDepA_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineEcefDepA_flags  :: Word8
+  , _msgBaselineEcefDepA_flags  :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -863,21 +867,21 @@
 -- GPS time is given by the preceding MSG_GPS_TIME with the matching time-of-
 -- week (tow).
 data MsgBaselineNedDepA = MsgBaselineNedDepA
-  { _msgBaselineNedDepA_tow      :: Word32
+  { _msgBaselineNedDepA_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineNedDepA_n        :: Int32
+  , _msgBaselineNedDepA_n        :: !Int32
     -- ^ Baseline North coordinate
-  , _msgBaselineNedDepA_e        :: Int32
+  , _msgBaselineNedDepA_e        :: !Int32
     -- ^ Baseline East coordinate
-  , _msgBaselineNedDepA_d        :: Int32
+  , _msgBaselineNedDepA_d        :: !Int32
     -- ^ Baseline Down coordinate
-  , _msgBaselineNedDepA_h_accuracy :: Word16
+  , _msgBaselineNedDepA_h_accuracy :: !Word16
     -- ^ Horizontal position accuracy estimate (not implemented). Defaults to 0.
-  , _msgBaselineNedDepA_v_accuracy :: Word16
+  , _msgBaselineNedDepA_v_accuracy :: !Word16
     -- ^ Vertical position accuracy estimate (not implemented). Defaults to 0.
-  , _msgBaselineNedDepA_n_sats   :: Word8
+  , _msgBaselineNedDepA_n_sats   :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineNedDepA_flags    :: Word8
+  , _msgBaselineNedDepA_flags    :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
@@ -918,19 +922,19 @@
 -- coordinates. The full GPS time is given by the preceding MSG_GPS_TIME with
 -- the matching time-of-week (tow).
 data MsgVelEcefDepA = MsgVelEcefDepA
-  { _msgVelEcefDepA_tow    :: Word32
+  { _msgVelEcefDepA_tow    :: !Word32
     -- ^ GPS Time of Week
-  , _msgVelEcefDepA_x      :: Int32
+  , _msgVelEcefDepA_x      :: !Int32
     -- ^ Velocity ECEF X coordinate
-  , _msgVelEcefDepA_y      :: Int32
+  , _msgVelEcefDepA_y      :: !Int32
     -- ^ Velocity ECEF Y coordinate
-  , _msgVelEcefDepA_z      :: Int32
+  , _msgVelEcefDepA_z      :: !Int32
     -- ^ Velocity ECEF Z coordinate
-  , _msgVelEcefDepA_accuracy :: Word16
+  , _msgVelEcefDepA_accuracy :: !Word16
     -- ^ Velocity accuracy estimate (not implemented). Defaults to 0.
-  , _msgVelEcefDepA_n_sats :: Word8
+  , _msgVelEcefDepA_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgVelEcefDepA_flags  :: Word8
+  , _msgVelEcefDepA_flags  :: !Word8
     -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
@@ -970,21 +974,21 @@
 -- plane centered at the current position. The full GPS time is given by the
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgVelNedDepA = MsgVelNedDepA
-  { _msgVelNedDepA_tow      :: Word32
+  { _msgVelNedDepA_tow      :: !Word32
     -- ^ GPS Time of Week
-  , _msgVelNedDepA_n        :: Int32
+  , _msgVelNedDepA_n        :: !Int32
     -- ^ Velocity North coordinate
-  , _msgVelNedDepA_e        :: Int32
+  , _msgVelNedDepA_e        :: !Int32
     -- ^ Velocity East coordinate
-  , _msgVelNedDepA_d        :: Int32
+  , _msgVelNedDepA_d        :: !Int32
     -- ^ Velocity Down coordinate
-  , _msgVelNedDepA_h_accuracy :: Word16
+  , _msgVelNedDepA_h_accuracy :: !Word16
     -- ^ Horizontal velocity accuracy estimate (not implemented). Defaults to 0.
-  , _msgVelNedDepA_v_accuracy :: Word16
+  , _msgVelNedDepA_v_accuracy :: !Word16
     -- ^ Vertical velocity accuracy estimate (not implemented). Defaults to 0.
-  , _msgVelNedDepA_n_sats   :: Word8
+  , _msgVelNedDepA_n_sats   :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgVelNedDepA_flags    :: Word8
+  , _msgVelNedDepA_flags    :: !Word8
     -- ^ Status flags (reserved)
   } deriving ( Show, Read, Eq )
 
@@ -1025,13 +1029,13 @@
 -- the rover relative to True North. The full GPS time is given by the
 -- preceding MSG_GPS_TIME with the matching time-of-week (tow).
 data MsgBaselineHeadingDepA = MsgBaselineHeadingDepA
-  { _msgBaselineHeadingDepA_tow   :: Word32
+  { _msgBaselineHeadingDepA_tow   :: !Word32
     -- ^ GPS Time of Week
-  , _msgBaselineHeadingDepA_heading :: Word32
+  , _msgBaselineHeadingDepA_heading :: !Word32
     -- ^ Heading
-  , _msgBaselineHeadingDepA_n_sats :: Word8
+  , _msgBaselineHeadingDepA_n_sats :: !Word8
     -- ^ Number of satellites used in solution
-  , _msgBaselineHeadingDepA_flags :: Word8
+  , _msgBaselineHeadingDepA_flags :: !Word8
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Ndb.hs b/src/SwiftNav/SBP/Ndb.hs
--- a/src/SwiftNav/SBP/Ndb.hs
+++ b/src/SwiftNav/SBP/Ndb.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Ndb
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -36,25 +40,25 @@
 -- This message is sent out when an object is stored into NDB. If needed
 -- message could also be sent out when fetching an object from NDB.
 data MsgNdbEvent = MsgNdbEvent
-  { _msgNdbEvent_recv_time     :: Word64
+  { _msgNdbEvent_recv_time     :: !Word64
     -- ^ HW time in milliseconds.
-  , _msgNdbEvent_event         :: Word8
+  , _msgNdbEvent_event         :: !Word8
     -- ^ Event type.
-  , _msgNdbEvent_object_type   :: Word8
+  , _msgNdbEvent_object_type   :: !Word8
     -- ^ Event object type.
-  , _msgNdbEvent_result        :: Word8
+  , _msgNdbEvent_result        :: !Word8
     -- ^ Event result.
-  , _msgNdbEvent_data_source   :: Word8
+  , _msgNdbEvent_data_source   :: !Word8
     -- ^ Data source for STORE event, reserved for other events.
-  , _msgNdbEvent_object_sid    :: GnssSignal16
+  , _msgNdbEvent_object_sid    :: !GnssSignal16
     -- ^ GNSS signal identifier, If object_type is Ephemeris OR Almanac, sid
     -- indicates for which signal the object belongs to. Reserved in other
     -- cases.
-  , _msgNdbEvent_src_sid       :: GnssSignal16
+  , _msgNdbEvent_src_sid       :: !GnssSignal16
     -- ^ GNSS signal identifier, If object_type is Almanac, Almanac WN, Iono OR
     -- L2C capabilities AND data_source is NDB_DS_RECEIVER sid indicates from
     -- which SV data was decoded. Reserved in other cases.
-  , _msgNdbEvent_original_sender :: Word16
+  , _msgNdbEvent_original_sender :: !Word16
     -- ^ A unique identifier of the sending hardware. For v1.0, set to the 2
     -- least significant bytes of the device serial number, valid only if
     -- data_source is NDB_DS_SBP. Reserved in case of other data_source.
diff --git a/src/SwiftNav/SBP/Observation.hs b/src/SwiftNav/SBP/Observation.hs
--- a/src/SwiftNav/SBP/Observation.hs
+++ b/src/SwiftNav/SBP/Observation.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Observation
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -32,9 +36,9 @@
 --
 -- Header of a GNSS observation message.
 data ObservationHeader = ObservationHeader
-  { _observationHeader_t   :: GpsTimeNano
+  { _observationHeader_t   :: !GpsTimeNano
     -- ^ GNSS time of this observation
-  , _observationHeader_n_obs :: Word8
+  , _observationHeader_n_obs :: !Word8
     -- ^ Total number of observations. First nibble is the size of the sequence
     -- (n), second nibble is the zero-indexed counter (ith packet of n)
   } deriving ( Show, Read, Eq )
@@ -58,9 +62,9 @@
 -- Q16.8 layout, i.e. 16-bits of whole doppler and 8-bits of fractional
 -- doppler. This doppler is defined as positive for approaching satellites.
 data Doppler = Doppler
-  { _doppler_i :: Int16
+  { _doppler_i :: !Int16
     -- ^ Doppler whole Hz
-  , _doppler_f :: Word8
+  , _doppler_f :: !Word8
     -- ^ Doppler fractional part
   } deriving ( Show, Read, Eq )
 
@@ -83,26 +87,26 @@
 -- observations are interoperable with 3rd party receivers and conform with
 -- typical RTCMv3 GNSS observations.
 data PackedObsContent = PackedObsContent
-  { _packedObsContent_P   :: Word32
+  { _packedObsContent_P   :: !Word32
     -- ^ Pseudorange observation
-  , _packedObsContent_L   :: CarrierPhase
+  , _packedObsContent_L   :: !CarrierPhase
     -- ^ Carrier phase observation with typical sign convention.
-  , _packedObsContent_D   :: Doppler
+  , _packedObsContent_D   :: !Doppler
     -- ^ Doppler observation with typical sign convention.
-  , _packedObsContent_cn0 :: Word8
+  , _packedObsContent_cn0 :: !Word8
     -- ^ Carrier-to-Noise density.  Zero implies invalid cn0.
-  , _packedObsContent_lock :: Word8
+  , _packedObsContent_lock :: !Word8
     -- ^ Lock timer. This value gives an indication of the time for which a
     -- signal has maintained continuous phase lock. Whenever a signal has lost
     -- and regained lock, this value is reset to zero. It is encoded according
     -- to DF402 from the RTCM 10403.2 Amendment 2 specification.  Valid values
     -- range from 0 to 15 and the most significant nibble is reserved for
     -- future use.
-  , _packedObsContent_flags :: Word8
+  , _packedObsContent_flags :: !Word8
     -- ^ Measurement status flags. A bit field of flags providing the status of
     -- this observation.  If this field is 0 it means only the Cn0 estimate for
     -- the signal is valid.
-  , _packedObsContent_sid :: GnssSignal16
+  , _packedObsContent_sid :: !GnssSignal16
     -- ^ GNSS signal identifier (16 bit)
   } deriving ( Show, Read, Eq )
 
@@ -141,9 +145,9 @@
 -- The observations are be interoperable with 3rd party receivers and conform
 -- with typical RTCMv3 GNSS observations.
 data MsgObs = MsgObs
-  { _msgObs_header :: ObservationHeader
+  { _msgObs_header :: !ObservationHeader
     -- ^ Header of a GPS observation message
-  , _msgObs_obs  :: [PackedObsContent]
+  , _msgObs_obs  :: ![PackedObsContent]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
@@ -173,11 +177,11 @@
 -- required to be a high-accuracy surveyed location of the base station. Any
 -- error here will result in an error in the pseudo-absolute position output.
 data MsgBasePosLlh = MsgBasePosLlh
-  { _msgBasePosLlh_lat  :: Double
+  { _msgBasePosLlh_lat  :: !Double
     -- ^ Latitude
-  , _msgBasePosLlh_lon  :: Double
+  , _msgBasePosLlh_lon  :: !Double
     -- ^ Longitude
-  , _msgBasePosLlh_height :: Double
+  , _msgBasePosLlh_height :: !Double
     -- ^ Height
   } deriving ( Show, Read, Eq )
 
@@ -210,11 +214,11 @@
 -- accuracy surveyed location of the base station. Any error here will result
 -- in an error in the pseudo-absolute position output.
 data MsgBasePosEcef = MsgBasePosEcef
-  { _msgBasePosEcef_x :: Double
+  { _msgBasePosEcef_x :: !Double
     -- ^ ECEF X coodinate
-  , _msgBasePosEcef_y :: Double
+  , _msgBasePosEcef_y :: !Double
     -- ^ ECEF Y coordinate
-  , _msgBasePosEcef_z :: Double
+  , _msgBasePosEcef_z :: !Double
     -- ^ ECEF Z coordinate
   } deriving ( Show, Read, Eq )
 
@@ -237,17 +241,17 @@
 $(makeLenses ''MsgBasePosEcef)
 
 data EphemerisCommonContent = EphemerisCommonContent
-  { _ephemerisCommonContent_sid        :: GnssSignal16
+  { _ephemerisCommonContent_sid        :: !GnssSignal16
     -- ^ GNSS signal identifier (16 bit)
-  , _ephemerisCommonContent_toe        :: GpsTimeSec
+  , _ephemerisCommonContent_toe        :: !GpsTimeSec
     -- ^ Time of Ephemerides
-  , _ephemerisCommonContent_ura        :: Double
+  , _ephemerisCommonContent_ura        :: !Double
     -- ^ User Range Accuracy
-  , _ephemerisCommonContent_fit_interval :: Word32
+  , _ephemerisCommonContent_fit_interval :: !Word32
     -- ^ Curve fit interval
-  , _ephemerisCommonContent_valid      :: Word8
+  , _ephemerisCommonContent_valid      :: !Word8
     -- ^ Status of ephemeris, 1 = valid, 0 = invalid
-  , _ephemerisCommonContent_health_bits :: Word8
+  , _ephemerisCommonContent_health_bits :: !Word8
     -- ^ Satellite health status. GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 SBAS: 0
     -- = valid, non-zero = invalid GLO: 0 = valid, non-zero = invalid
   } deriving ( Show, Read, Eq )
@@ -274,17 +278,17 @@
 $(makeLenses ''EphemerisCommonContent)
 
 data EphemerisCommonContentDepA = EphemerisCommonContentDepA
-  { _ephemerisCommonContentDepA_sid        :: GnssSignal
+  { _ephemerisCommonContentDepA_sid        :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _ephemerisCommonContentDepA_toe        :: GpsTime
+  , _ephemerisCommonContentDepA_toe        :: !GpsTime
     -- ^ Time of Ephemerides
-  , _ephemerisCommonContentDepA_ura        :: Double
+  , _ephemerisCommonContentDepA_ura        :: !Double
     -- ^ User Range Accuracy
-  , _ephemerisCommonContentDepA_fit_interval :: Word32
+  , _ephemerisCommonContentDepA_fit_interval :: !Word32
     -- ^ Curve fit interval
-  , _ephemerisCommonContentDepA_valid      :: Word8
+  , _ephemerisCommonContentDepA_valid      :: !Word8
     -- ^ Status of ephemeris, 1 = valid, 0 = invalid
-  , _ephemerisCommonContentDepA_health_bits :: Word8
+  , _ephemerisCommonContentDepA_health_bits :: !Word8
     -- ^ Satellite health status. GPS: ICD-GPS-200, chapter 20.3.3.3.1.4 SBAS: 0
     -- = valid, non-zero = invalid GLO: 0 = valid, non-zero = invalid
   } deriving ( Show, Read, Eq )
@@ -320,55 +324,55 @@
 -- see the Navstar GPS Space Segment/Navigation user interfaces (ICD-GPS-200,
 -- Table 20-III) for more details.
 data MsgEphemerisGpsDepE = MsgEphemerisGpsDepE
-  { _msgEphemerisGpsDepE_common :: EphemerisCommonContentDepA
+  { _msgEphemerisGpsDepE_common :: !EphemerisCommonContentDepA
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGpsDepE_tgd    :: Double
+  , _msgEphemerisGpsDepE_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisGpsDepE_c_rs   :: Double
+  , _msgEphemerisGpsDepE_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisGpsDepE_c_rc   :: Double
+  , _msgEphemerisGpsDepE_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisGpsDepE_c_uc   :: Double
+  , _msgEphemerisGpsDepE_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisGpsDepE_c_us   :: Double
+  , _msgEphemerisGpsDepE_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisGpsDepE_c_ic   :: Double
+  , _msgEphemerisGpsDepE_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisGpsDepE_c_is   :: Double
+  , _msgEphemerisGpsDepE_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisGpsDepE_dn     :: Double
+  , _msgEphemerisGpsDepE_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisGpsDepE_m0     :: Double
+  , _msgEphemerisGpsDepE_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisGpsDepE_ecc    :: Double
+  , _msgEphemerisGpsDepE_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisGpsDepE_sqrta  :: Double
+  , _msgEphemerisGpsDepE_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisGpsDepE_omega0 :: Double
+  , _msgEphemerisGpsDepE_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisGpsDepE_omegadot :: Double
+  , _msgEphemerisGpsDepE_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisGpsDepE_w      :: Double
+  , _msgEphemerisGpsDepE_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisGpsDepE_inc    :: Double
+  , _msgEphemerisGpsDepE_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisGpsDepE_inc_dot :: Double
+  , _msgEphemerisGpsDepE_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisGpsDepE_af0    :: Double
+  , _msgEphemerisGpsDepE_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisGpsDepE_af1    :: Double
+  , _msgEphemerisGpsDepE_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisGpsDepE_af2    :: Double
+  , _msgEphemerisGpsDepE_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisGpsDepE_toc    :: GpsTime
+  , _msgEphemerisGpsDepE_toc    :: !GpsTime
     -- ^ Clock reference
-  , _msgEphemerisGpsDepE_iode   :: Word8
+  , _msgEphemerisGpsDepE_iode   :: !Word8
     -- ^ Issue of ephemeris data
-  , _msgEphemerisGpsDepE_iodc   :: Word16
+  , _msgEphemerisGpsDepE_iodc   :: !Word16
     -- ^ Issue of clock data
   } deriving ( Show, Read, Eq )
 
@@ -440,55 +444,55 @@
 -- see the Navstar GPS Space Segment/Navigation user interfaces (ICD-GPS-200,
 -- Table 20-III) for more details.
 data MsgEphemerisGps = MsgEphemerisGps
-  { _msgEphemerisGps_common :: EphemerisCommonContent
+  { _msgEphemerisGps_common :: !EphemerisCommonContent
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGps_tgd    :: Double
+  , _msgEphemerisGps_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisGps_c_rs   :: Double
+  , _msgEphemerisGps_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisGps_c_rc   :: Double
+  , _msgEphemerisGps_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisGps_c_uc   :: Double
+  , _msgEphemerisGps_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisGps_c_us   :: Double
+  , _msgEphemerisGps_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisGps_c_ic   :: Double
+  , _msgEphemerisGps_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisGps_c_is   :: Double
+  , _msgEphemerisGps_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisGps_dn     :: Double
+  , _msgEphemerisGps_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisGps_m0     :: Double
+  , _msgEphemerisGps_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisGps_ecc    :: Double
+  , _msgEphemerisGps_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisGps_sqrta  :: Double
+  , _msgEphemerisGps_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisGps_omega0 :: Double
+  , _msgEphemerisGps_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisGps_omegadot :: Double
+  , _msgEphemerisGps_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisGps_w      :: Double
+  , _msgEphemerisGps_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisGps_inc    :: Double
+  , _msgEphemerisGps_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisGps_inc_dot :: Double
+  , _msgEphemerisGps_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisGps_af0    :: Double
+  , _msgEphemerisGps_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisGps_af1    :: Double
+  , _msgEphemerisGps_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisGps_af2    :: Double
+  , _msgEphemerisGps_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisGps_toc    :: GpsTimeSec
+  , _msgEphemerisGps_toc    :: !GpsTimeSec
     -- ^ Clock reference
-  , _msgEphemerisGps_iode   :: Word8
+  , _msgEphemerisGps_iode   :: !Word8
     -- ^ Issue of ephemeris data
-  , _msgEphemerisGps_iodc   :: Word16
+  , _msgEphemerisGps_iodc   :: !Word16
     -- ^ Issue of clock data
   } deriving ( Show, Read, Eq )
 
@@ -554,17 +558,17 @@
 msgEphemerisSbasDepA = 0x0082
 
 data MsgEphemerisSbasDepA = MsgEphemerisSbasDepA
-  { _msgEphemerisSbasDepA_common :: EphemerisCommonContentDepA
+  { _msgEphemerisSbasDepA_common :: !EphemerisCommonContentDepA
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisSbasDepA_pos  :: [Double]
+  , _msgEphemerisSbasDepA_pos  :: ![Double]
     -- ^ Position of the GEO at time toe
-  , _msgEphemerisSbasDepA_vel  :: [Double]
+  , _msgEphemerisSbasDepA_vel  :: ![Double]
     -- ^ Velocity of the GEO at time toe
-  , _msgEphemerisSbasDepA_acc  :: [Double]
+  , _msgEphemerisSbasDepA_acc  :: ![Double]
     -- ^ Acceleration of the GEO at time toe
-  , _msgEphemerisSbasDepA_a_gf0 :: Double
+  , _msgEphemerisSbasDepA_a_gf0 :: !Double
     -- ^ Time offset of the GEO clock w.r.t. SBAS Network Time
-  , _msgEphemerisSbasDepA_a_gf1 :: Double
+  , _msgEphemerisSbasDepA_a_gf1 :: !Double
     -- ^ Drift of the GEO clock w.r.t. SBAS Network Time
   } deriving ( Show, Read, Eq )
 
@@ -602,17 +606,17 @@
 -- see the GLO ICD 5.1 "Table 4.5 Characteristics of words of immediate
 -- information (ephemeris parameters)" for more details.
 data MsgEphemerisGloDepA = MsgEphemerisGloDepA
-  { _msgEphemerisGloDepA_common :: EphemerisCommonContentDepA
+  { _msgEphemerisGloDepA_common :: !EphemerisCommonContentDepA
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGloDepA_gamma :: Double
+  , _msgEphemerisGloDepA_gamma :: !Double
     -- ^ Relative deviation of predicted carrier frequency from nominal
-  , _msgEphemerisGloDepA_tau  :: Double
+  , _msgEphemerisGloDepA_tau  :: !Double
     -- ^ Correction to the SV time
-  , _msgEphemerisGloDepA_pos  :: [Double]
+  , _msgEphemerisGloDepA_pos  :: ![Double]
     -- ^ Position of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepA_vel  :: [Double]
+  , _msgEphemerisGloDepA_vel  :: ![Double]
     -- ^ Velocity vector of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepA_acc  :: [Double]
+  , _msgEphemerisGloDepA_acc  :: ![Double]
     -- ^ Acceleration vector of the SV at tb in PZ-90.02 coordinates sys
   } deriving ( Show, Read, Eq )
 
@@ -644,17 +648,17 @@
 msgEphemerisSbas = 0x0084
 
 data MsgEphemerisSbas = MsgEphemerisSbas
-  { _msgEphemerisSbas_common :: EphemerisCommonContent
+  { _msgEphemerisSbas_common :: !EphemerisCommonContent
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisSbas_pos  :: [Double]
+  , _msgEphemerisSbas_pos  :: ![Double]
     -- ^ Position of the GEO at time toe
-  , _msgEphemerisSbas_vel  :: [Double]
+  , _msgEphemerisSbas_vel  :: ![Double]
     -- ^ Velocity of the GEO at time toe
-  , _msgEphemerisSbas_acc  :: [Double]
+  , _msgEphemerisSbas_acc  :: ![Double]
     -- ^ Acceleration of the GEO at time toe
-  , _msgEphemerisSbas_a_gf0 :: Double
+  , _msgEphemerisSbas_a_gf0 :: !Double
     -- ^ Time offset of the GEO clock w.r.t. SBAS Network Time
-  , _msgEphemerisSbas_a_gf1 :: Double
+  , _msgEphemerisSbas_a_gf1 :: !Double
     -- ^ Drift of the GEO clock w.r.t. SBAS Network Time
   } deriving ( Show, Read, Eq )
 
@@ -692,17 +696,17 @@
 -- see the GLO ICD 5.1 "Table 4.5 Characteristics of words of immediate
 -- information (ephemeris parameters)" for more details.
 data MsgEphemerisGloDepB = MsgEphemerisGloDepB
-  { _msgEphemerisGloDepB_common :: EphemerisCommonContent
+  { _msgEphemerisGloDepB_common :: !EphemerisCommonContent
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGloDepB_gamma :: Double
+  , _msgEphemerisGloDepB_gamma :: !Double
     -- ^ Relative deviation of predicted carrier frequency from nominal
-  , _msgEphemerisGloDepB_tau  :: Double
+  , _msgEphemerisGloDepB_tau  :: !Double
     -- ^ Correction to the SV time
-  , _msgEphemerisGloDepB_pos  :: [Double]
+  , _msgEphemerisGloDepB_pos  :: ![Double]
     -- ^ Position of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepB_vel  :: [Double]
+  , _msgEphemerisGloDepB_vel  :: ![Double]
     -- ^ Velocity vector of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepB_acc  :: [Double]
+  , _msgEphemerisGloDepB_acc  :: ![Double]
     -- ^ Acceleration vector of the SV at tb in PZ-90.02 coordinates sys
   } deriving ( Show, Read, Eq )
 
@@ -740,21 +744,21 @@
 -- see the GLO ICD 5.1 "Table 4.5 Characteristics of words of immediate
 -- information (ephemeris parameters)" for more details.
 data MsgEphemerisGloDepC = MsgEphemerisGloDepC
-  { _msgEphemerisGloDepC_common :: EphemerisCommonContent
+  { _msgEphemerisGloDepC_common :: !EphemerisCommonContent
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGloDepC_gamma :: Double
+  , _msgEphemerisGloDepC_gamma :: !Double
     -- ^ Relative deviation of predicted carrier frequency from nominal
-  , _msgEphemerisGloDepC_tau  :: Double
+  , _msgEphemerisGloDepC_tau  :: !Double
     -- ^ Correction to the SV time
-  , _msgEphemerisGloDepC_d_tau :: Double
+  , _msgEphemerisGloDepC_d_tau :: !Double
     -- ^ Equipment delay between L1 and L2
-  , _msgEphemerisGloDepC_pos  :: [Double]
+  , _msgEphemerisGloDepC_pos  :: ![Double]
     -- ^ Position of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepC_vel  :: [Double]
+  , _msgEphemerisGloDepC_vel  :: ![Double]
     -- ^ Velocity vector of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGloDepC_acc  :: [Double]
+  , _msgEphemerisGloDepC_acc  :: ![Double]
     -- ^ Acceleration vector of the SV at tb in PZ-90.02 coordinates sys
-  , _msgEphemerisGloDepC_fcn  :: Word8
+  , _msgEphemerisGloDepC_fcn  :: !Word8
     -- ^ Frequency slot. FCN+8 (that is [1..14]). 0 or 0xFF for invalid
   } deriving ( Show, Read, Eq )
 
@@ -796,23 +800,23 @@
 -- see the GLO ICD 5.1 "Table 4.5 Characteristics of words of immediate
 -- information (ephemeris parameters)" for more details.
 data MsgEphemerisGlo = MsgEphemerisGlo
-  { _msgEphemerisGlo_common :: EphemerisCommonContent
+  { _msgEphemerisGlo_common :: !EphemerisCommonContent
     -- ^ Values common for all ephemeris types
-  , _msgEphemerisGlo_gamma :: Double
+  , _msgEphemerisGlo_gamma :: !Double
     -- ^ Relative deviation of predicted carrier frequency from nominal
-  , _msgEphemerisGlo_tau  :: Double
+  , _msgEphemerisGlo_tau  :: !Double
     -- ^ Correction to the SV time
-  , _msgEphemerisGlo_d_tau :: Double
+  , _msgEphemerisGlo_d_tau :: !Double
     -- ^ Equipment delay between L1 and L2
-  , _msgEphemerisGlo_pos  :: [Double]
+  , _msgEphemerisGlo_pos  :: ![Double]
     -- ^ Position of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGlo_vel  :: [Double]
+  , _msgEphemerisGlo_vel  :: ![Double]
     -- ^ Velocity vector of the SV at tb in PZ-90.02 coordinates system
-  , _msgEphemerisGlo_acc  :: [Double]
+  , _msgEphemerisGlo_acc  :: ![Double]
     -- ^ Acceleration vector of the SV at tb in PZ-90.02 coordinates sys
-  , _msgEphemerisGlo_fcn  :: Word8
+  , _msgEphemerisGlo_fcn  :: !Word8
     -- ^ Frequency slot. FCN+8 (that is [1..14]). 0 or 0xFF for invalid
-  , _msgEphemerisGlo_iod  :: Word8
+  , _msgEphemerisGlo_iod  :: !Word8
     -- ^ Issue of ephemeris data
   } deriving ( Show, Read, Eq )
 
@@ -856,67 +860,67 @@
 -- see the Navstar GPS Space Segment/Navigation user interfaces (ICD-GPS-200,
 -- Table 20-III) for more details.
 data MsgEphemerisDepD = MsgEphemerisDepD
-  { _msgEphemerisDepD_tgd    :: Double
+  { _msgEphemerisDepD_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisDepD_c_rs   :: Double
+  , _msgEphemerisDepD_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisDepD_c_rc   :: Double
+  , _msgEphemerisDepD_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisDepD_c_uc   :: Double
+  , _msgEphemerisDepD_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepD_c_us   :: Double
+  , _msgEphemerisDepD_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepD_c_ic   :: Double
+  , _msgEphemerisDepD_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepD_c_is   :: Double
+  , _msgEphemerisDepD_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepD_dn     :: Double
+  , _msgEphemerisDepD_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisDepD_m0     :: Double
+  , _msgEphemerisDepD_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisDepD_ecc    :: Double
+  , _msgEphemerisDepD_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisDepD_sqrta  :: Double
+  , _msgEphemerisDepD_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisDepD_omega0 :: Double
+  , _msgEphemerisDepD_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisDepD_omegadot :: Double
+  , _msgEphemerisDepD_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisDepD_w      :: Double
+  , _msgEphemerisDepD_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisDepD_inc    :: Double
+  , _msgEphemerisDepD_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisDepD_inc_dot :: Double
+  , _msgEphemerisDepD_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisDepD_af0    :: Double
+  , _msgEphemerisDepD_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisDepD_af1    :: Double
+  , _msgEphemerisDepD_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisDepD_af2    :: Double
+  , _msgEphemerisDepD_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisDepD_toe_tow :: Double
+  , _msgEphemerisDepD_toe_tow :: !Double
     -- ^ Time of week
-  , _msgEphemerisDepD_toe_wn :: Word16
+  , _msgEphemerisDepD_toe_wn :: !Word16
     -- ^ Week number
-  , _msgEphemerisDepD_toc_tow :: Double
+  , _msgEphemerisDepD_toc_tow :: !Double
     -- ^ Clock reference time of week
-  , _msgEphemerisDepD_toc_wn :: Word16
+  , _msgEphemerisDepD_toc_wn :: !Word16
     -- ^ Clock reference week number
-  , _msgEphemerisDepD_valid  :: Word8
+  , _msgEphemerisDepD_valid  :: !Word8
     -- ^ Is valid?
-  , _msgEphemerisDepD_healthy :: Word8
+  , _msgEphemerisDepD_healthy :: !Word8
     -- ^ Satellite is healthy?
-  , _msgEphemerisDepD_sid    :: GnssSignal
+  , _msgEphemerisDepD_sid    :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _msgEphemerisDepD_iode   :: Word8
+  , _msgEphemerisDepD_iode   :: !Word8
     -- ^ Issue of ephemeris data
-  , _msgEphemerisDepD_iodc   :: Word16
+  , _msgEphemerisDepD_iodc   :: !Word16
     -- ^ Issue of clock data
-  , _msgEphemerisDepD_reserved :: Word32
+  , _msgEphemerisDepD_reserved :: !Word32
     -- ^ Reserved field
   } deriving ( Show, Read, Eq )
 
@@ -997,61 +1001,61 @@
 --
 -- Deprecated.
 data MsgEphemerisDepA = MsgEphemerisDepA
-  { _msgEphemerisDepA_tgd    :: Double
+  { _msgEphemerisDepA_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisDepA_c_rs   :: Double
+  , _msgEphemerisDepA_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisDepA_c_rc   :: Double
+  , _msgEphemerisDepA_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisDepA_c_uc   :: Double
+  , _msgEphemerisDepA_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepA_c_us   :: Double
+  , _msgEphemerisDepA_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepA_c_ic   :: Double
+  , _msgEphemerisDepA_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepA_c_is   :: Double
+  , _msgEphemerisDepA_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepA_dn     :: Double
+  , _msgEphemerisDepA_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisDepA_m0     :: Double
+  , _msgEphemerisDepA_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisDepA_ecc    :: Double
+  , _msgEphemerisDepA_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisDepA_sqrta  :: Double
+  , _msgEphemerisDepA_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisDepA_omega0 :: Double
+  , _msgEphemerisDepA_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisDepA_omegadot :: Double
+  , _msgEphemerisDepA_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisDepA_w      :: Double
+  , _msgEphemerisDepA_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisDepA_inc    :: Double
+  , _msgEphemerisDepA_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisDepA_inc_dot :: Double
+  , _msgEphemerisDepA_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisDepA_af0    :: Double
+  , _msgEphemerisDepA_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisDepA_af1    :: Double
+  , _msgEphemerisDepA_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisDepA_af2    :: Double
+  , _msgEphemerisDepA_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisDepA_toe_tow :: Double
+  , _msgEphemerisDepA_toe_tow :: !Double
     -- ^ Time of week
-  , _msgEphemerisDepA_toe_wn :: Word16
+  , _msgEphemerisDepA_toe_wn :: !Word16
     -- ^ Week number
-  , _msgEphemerisDepA_toc_tow :: Double
+  , _msgEphemerisDepA_toc_tow :: !Double
     -- ^ Clock reference time of week
-  , _msgEphemerisDepA_toc_wn :: Word16
+  , _msgEphemerisDepA_toc_wn :: !Word16
     -- ^ Clock reference week number
-  , _msgEphemerisDepA_valid  :: Word8
+  , _msgEphemerisDepA_valid  :: !Word8
     -- ^ Is valid?
-  , _msgEphemerisDepA_healthy :: Word8
+  , _msgEphemerisDepA_healthy :: !Word8
     -- ^ Satellite is healthy?
-  , _msgEphemerisDepA_prn    :: Word8
+  , _msgEphemerisDepA_prn    :: !Word8
     -- ^ PRN being tracked
   } deriving ( Show, Read, Eq )
 
@@ -1126,63 +1130,63 @@
 --
 -- Deprecated.
 data MsgEphemerisDepB = MsgEphemerisDepB
-  { _msgEphemerisDepB_tgd    :: Double
+  { _msgEphemerisDepB_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisDepB_c_rs   :: Double
+  , _msgEphemerisDepB_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisDepB_c_rc   :: Double
+  , _msgEphemerisDepB_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisDepB_c_uc   :: Double
+  , _msgEphemerisDepB_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepB_c_us   :: Double
+  , _msgEphemerisDepB_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepB_c_ic   :: Double
+  , _msgEphemerisDepB_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepB_c_is   :: Double
+  , _msgEphemerisDepB_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepB_dn     :: Double
+  , _msgEphemerisDepB_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisDepB_m0     :: Double
+  , _msgEphemerisDepB_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisDepB_ecc    :: Double
+  , _msgEphemerisDepB_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisDepB_sqrta  :: Double
+  , _msgEphemerisDepB_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisDepB_omega0 :: Double
+  , _msgEphemerisDepB_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisDepB_omegadot :: Double
+  , _msgEphemerisDepB_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisDepB_w      :: Double
+  , _msgEphemerisDepB_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisDepB_inc    :: Double
+  , _msgEphemerisDepB_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisDepB_inc_dot :: Double
+  , _msgEphemerisDepB_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisDepB_af0    :: Double
+  , _msgEphemerisDepB_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisDepB_af1    :: Double
+  , _msgEphemerisDepB_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisDepB_af2    :: Double
+  , _msgEphemerisDepB_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisDepB_toe_tow :: Double
+  , _msgEphemerisDepB_toe_tow :: !Double
     -- ^ Time of week
-  , _msgEphemerisDepB_toe_wn :: Word16
+  , _msgEphemerisDepB_toe_wn :: !Word16
     -- ^ Week number
-  , _msgEphemerisDepB_toc_tow :: Double
+  , _msgEphemerisDepB_toc_tow :: !Double
     -- ^ Clock reference time of week
-  , _msgEphemerisDepB_toc_wn :: Word16
+  , _msgEphemerisDepB_toc_wn :: !Word16
     -- ^ Clock reference week number
-  , _msgEphemerisDepB_valid  :: Word8
+  , _msgEphemerisDepB_valid  :: !Word8
     -- ^ Is valid?
-  , _msgEphemerisDepB_healthy :: Word8
+  , _msgEphemerisDepB_healthy :: !Word8
     -- ^ Satellite is healthy?
-  , _msgEphemerisDepB_prn    :: Word8
+  , _msgEphemerisDepB_prn    :: !Word8
     -- ^ PRN being tracked
-  , _msgEphemerisDepB_iode   :: Word8
+  , _msgEphemerisDepB_iode   :: !Word8
     -- ^ Issue of ephemeris data
   } deriving ( Show, Read, Eq )
 
@@ -1262,67 +1266,67 @@
 -- see the Navstar GPS Space Segment/Navigation user interfaces (ICD-GPS-200,
 -- Table 20-III) for more details.
 data MsgEphemerisDepC = MsgEphemerisDepC
-  { _msgEphemerisDepC_tgd    :: Double
+  { _msgEphemerisDepC_tgd    :: !Double
     -- ^ Group delay differential between L1 and L2
-  , _msgEphemerisDepC_c_rs   :: Double
+  , _msgEphemerisDepC_c_rs   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the orbit radius
-  , _msgEphemerisDepC_c_rc   :: Double
+  , _msgEphemerisDepC_c_rc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the orbit radius
-  , _msgEphemerisDepC_c_uc   :: Double
+  , _msgEphemerisDepC_c_uc   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepC_c_us   :: Double
+  , _msgEphemerisDepC_c_us   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the argument of
     -- latitude
-  , _msgEphemerisDepC_c_ic   :: Double
+  , _msgEphemerisDepC_c_ic   :: !Double
     -- ^ Amplitude of the cosine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepC_c_is   :: Double
+  , _msgEphemerisDepC_c_is   :: !Double
     -- ^ Amplitude of the sine harmonic correction term to the angle of
     -- inclination
-  , _msgEphemerisDepC_dn     :: Double
+  , _msgEphemerisDepC_dn     :: !Double
     -- ^ Mean motion difference
-  , _msgEphemerisDepC_m0     :: Double
+  , _msgEphemerisDepC_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgEphemerisDepC_ecc    :: Double
+  , _msgEphemerisDepC_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgEphemerisDepC_sqrta  :: Double
+  , _msgEphemerisDepC_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgEphemerisDepC_omega0 :: Double
+  , _msgEphemerisDepC_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgEphemerisDepC_omegadot :: Double
+  , _msgEphemerisDepC_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgEphemerisDepC_w      :: Double
+  , _msgEphemerisDepC_w      :: !Double
     -- ^ Argument of perigee
-  , _msgEphemerisDepC_inc    :: Double
+  , _msgEphemerisDepC_inc    :: !Double
     -- ^ Inclination
-  , _msgEphemerisDepC_inc_dot :: Double
+  , _msgEphemerisDepC_inc_dot :: !Double
     -- ^ Inclination first derivative
-  , _msgEphemerisDepC_af0    :: Double
+  , _msgEphemerisDepC_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgEphemerisDepC_af1    :: Double
+  , _msgEphemerisDepC_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
-  , _msgEphemerisDepC_af2    :: Double
+  , _msgEphemerisDepC_af2    :: !Double
     -- ^ Polynomial clock correction coefficient (rate of clock drift)
-  , _msgEphemerisDepC_toe_tow :: Double
+  , _msgEphemerisDepC_toe_tow :: !Double
     -- ^ Time of week
-  , _msgEphemerisDepC_toe_wn :: Word16
+  , _msgEphemerisDepC_toe_wn :: !Word16
     -- ^ Week number
-  , _msgEphemerisDepC_toc_tow :: Double
+  , _msgEphemerisDepC_toc_tow :: !Double
     -- ^ Clock reference time of week
-  , _msgEphemerisDepC_toc_wn :: Word16
+  , _msgEphemerisDepC_toc_wn :: !Word16
     -- ^ Clock reference week number
-  , _msgEphemerisDepC_valid  :: Word8
+  , _msgEphemerisDepC_valid  :: !Word8
     -- ^ Is valid?
-  , _msgEphemerisDepC_healthy :: Word8
+  , _msgEphemerisDepC_healthy :: !Word8
     -- ^ Satellite is healthy?
-  , _msgEphemerisDepC_sid    :: GnssSignal
+  , _msgEphemerisDepC_sid    :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _msgEphemerisDepC_iode   :: Word8
+  , _msgEphemerisDepC_iode   :: !Word8
     -- ^ Issue of ephemeris data
-  , _msgEphemerisDepC_iodc   :: Word16
+  , _msgEphemerisDepC_iodc   :: !Word16
     -- ^ Issue of clock data
-  , _msgEphemerisDepC_reserved :: Word32
+  , _msgEphemerisDepC_reserved :: !Word32
     -- ^ Reserved field
   } deriving ( Show, Read, Eq )
 
@@ -1400,9 +1404,9 @@
 --
 -- Header of a GPS observation message.
 data ObservationHeaderDep = ObservationHeaderDep
-  { _observationHeaderDep_t   :: GpsTime
+  { _observationHeaderDep_t   :: !GpsTime
     -- ^ GPS time of this observation
-  , _observationHeaderDep_n_obs :: Word8
+  , _observationHeaderDep_n_obs :: !Word8
     -- ^ Total number of observations. First nibble is the size of the sequence
     -- (n), second nibble is the zero-indexed counter (ith packet of n)
   } deriving ( Show, Read, Eq )
@@ -1427,9 +1431,9 @@
 -- fractional cycles. This has the opposite sign convention than a typical GPS
 -- receiver and the phase has the opposite sign as the pseudorange.
 data CarrierPhaseDepA = CarrierPhaseDepA
-  { _carrierPhaseDepA_i :: Int32
+  { _carrierPhaseDepA_i :: !Int32
     -- ^ Carrier phase whole cycles
-  , _carrierPhaseDepA_f :: Word8
+  , _carrierPhaseDepA_f :: !Word8
     -- ^ Carrier phase fractional part
   } deriving ( Show, Read, Eq )
 
@@ -1450,17 +1454,17 @@
 --
 -- Deprecated.
 data PackedObsContentDepA = PackedObsContentDepA
-  { _packedObsContentDepA_P  :: Word32
+  { _packedObsContentDepA_P  :: !Word32
     -- ^ Pseudorange observation
-  , _packedObsContentDepA_L  :: CarrierPhaseDepA
+  , _packedObsContentDepA_L  :: !CarrierPhaseDepA
     -- ^ Carrier phase observation with opposite sign from typical convention
-  , _packedObsContentDepA_cn0 :: Word8
+  , _packedObsContentDepA_cn0 :: !Word8
     -- ^ Carrier-to-Noise density
-  , _packedObsContentDepA_lock :: Word16
+  , _packedObsContentDepA_lock :: !Word16
     -- ^ Lock indicator. This value changes whenever a satellite signal has lost
     -- and regained lock, indicating that the carrier phase ambiguity may have
     -- changed.
-  , _packedObsContentDepA_prn :: Word8
+  , _packedObsContentDepA_prn :: !Word8
     -- ^ PRN-1 identifier of the satellite signal
   } deriving ( Show, Read, Eq )
 
@@ -1488,17 +1492,17 @@
 -- Pseudorange and carrier phase observation for a satellite being tracked.
 -- Pseudoranges are referenced to a nominal pseudorange.
 data PackedObsContentDepB = PackedObsContentDepB
-  { _packedObsContentDepB_P  :: Word32
+  { _packedObsContentDepB_P  :: !Word32
     -- ^ Pseudorange observation
-  , _packedObsContentDepB_L  :: CarrierPhaseDepA
+  , _packedObsContentDepB_L  :: !CarrierPhaseDepA
     -- ^ Carrier phase observation with opposite sign from typical convention.
-  , _packedObsContentDepB_cn0 :: Word8
+  , _packedObsContentDepB_cn0 :: !Word8
     -- ^ Carrier-to-Noise density
-  , _packedObsContentDepB_lock :: Word16
+  , _packedObsContentDepB_lock :: !Word16
     -- ^ Lock indicator. This value changes whenever a satellite signal has lost
     -- and regained lock, indicating that the carrier phase ambiguity may have
     -- changed.
-  , _packedObsContentDepB_sid :: GnssSignal
+  , _packedObsContentDepB_sid :: !GnssSignal
     -- ^ GNSS signal identifier
   } deriving ( Show, Read, Eq )
 
@@ -1527,17 +1531,17 @@
 -- observations are be interoperable with 3rd party receivers and conform with
 -- typical RTCMv3 GNSS observations.
 data PackedObsContentDepC = PackedObsContentDepC
-  { _packedObsContentDepC_P  :: Word32
+  { _packedObsContentDepC_P  :: !Word32
     -- ^ Pseudorange observation
-  , _packedObsContentDepC_L  :: CarrierPhase
+  , _packedObsContentDepC_L  :: !CarrierPhase
     -- ^ Carrier phase observation with typical sign convention.
-  , _packedObsContentDepC_cn0 :: Word8
+  , _packedObsContentDepC_cn0 :: !Word8
     -- ^ Carrier-to-Noise density
-  , _packedObsContentDepC_lock :: Word16
+  , _packedObsContentDepC_lock :: !Word16
     -- ^ Lock indicator. This value changes whenever a satellite signal has lost
     -- and regained lock, indicating that the carrier phase ambiguity may have
     -- changed.
-  , _packedObsContentDepC_sid :: GnssSignal
+  , _packedObsContentDepC_sid :: !GnssSignal
     -- ^ GNSS signal identifier
   } deriving ( Show, Read, Eq )
 
@@ -1567,9 +1571,9 @@
 --
 -- Deprecated.
 data MsgObsDepA = MsgObsDepA
-  { _msgObsDepA_header :: ObservationHeaderDep
+  { _msgObsDepA_header :: !ObservationHeaderDep
     -- ^ Header of a GPS observation message
-  , _msgObsDepA_obs  :: [PackedObsContentDepA]
+  , _msgObsDepA_obs  :: ![PackedObsContentDepA]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
@@ -1599,9 +1603,9 @@
 -- referenced to a nominal pseudorange which are not interoperable with most
 -- 3rd party GNSS receievers or typical RTCMv3 observations.
 data MsgObsDepB = MsgObsDepB
-  { _msgObsDepB_header :: ObservationHeaderDep
+  { _msgObsDepB_header :: !ObservationHeaderDep
     -- ^ Header of a GPS observation message
-  , _msgObsDepB_obs  :: [PackedObsContentDepB]
+  , _msgObsDepB_obs  :: ![PackedObsContentDepB]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
@@ -1633,9 +1637,9 @@
 -- The observations are interoperable with 3rd party receivers and conform with
 -- typical RTCMv3 GNSS observations.
 data MsgObsDepC = MsgObsDepC
-  { _msgObsDepC_header :: ObservationHeaderDep
+  { _msgObsDepC_header :: !ObservationHeaderDep
     -- ^ Header of a GPS observation message
-  , _msgObsDepC_obs  :: [PackedObsContentDepC]
+  , _msgObsDepC_obs  :: ![PackedObsContentDepC]
     -- ^ Pseudorange and carrier phase observation for a satellite being tracked.
   } deriving ( Show, Read, Eq )
 
@@ -1664,16 +1668,16 @@
 -- utilize the ionospheric model for computation of the ionospheric delay.
 -- Please see ICD-GPS-200 (Chapter 20.3.3.5.1.7) for more details.
 data MsgIono = MsgIono
-  { _msgIono_t_nmct :: GpsTimeSec
+  { _msgIono_t_nmct :: !GpsTimeSec
     -- ^ Navigation Message Correction Table Valitidy Time
-  , _msgIono_a0   :: Double
-  , _msgIono_a1   :: Double
-  , _msgIono_a2   :: Double
-  , _msgIono_a3   :: Double
-  , _msgIono_b0   :: Double
-  , _msgIono_b1   :: Double
-  , _msgIono_b2   :: Double
-  , _msgIono_b3   :: Double
+  , _msgIono_a0   :: !Double
+  , _msgIono_a1   :: !Double
+  , _msgIono_a2   :: !Double
+  , _msgIono_a3   :: !Double
+  , _msgIono_b0   :: !Double
+  , _msgIono_b1   :: !Double
+  , _msgIono_b2   :: !Double
+  , _msgIono_b3   :: !Double
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgIono where
@@ -1713,9 +1717,9 @@
 --
 -- Please see ICD-GPS-200 (Chapter 20.3.3.5.1.4) for more details.
 data MsgSvConfigurationGps = MsgSvConfigurationGps
-  { _msgSvConfigurationGps_t_nmct :: GpsTimeSec
+  { _msgSvConfigurationGps_t_nmct :: !GpsTimeSec
     -- ^ Navigation Message Correction Table Valitidy Time
-  , _msgSvConfigurationGps_l2c_mask :: Word32
+  , _msgSvConfigurationGps_l2c_mask :: !Word32
     -- ^ L2C capability mask, SV32 bit being MSB, SV1 bit being LSB
   } deriving ( Show, Read, Eq )
 
@@ -1742,16 +1746,16 @@
 --
 -- Please see ICD-GPS-200 (30.3.3.3.1.1) for more details.
 data MsgGroupDelayDepA = MsgGroupDelayDepA
-  { _msgGroupDelayDepA_t_op   :: GpsTime
+  { _msgGroupDelayDepA_t_op   :: !GpsTime
     -- ^ Data Predict Time of Week
-  , _msgGroupDelayDepA_prn    :: Word8
+  , _msgGroupDelayDepA_prn    :: !Word8
     -- ^ Satellite number
-  , _msgGroupDelayDepA_valid  :: Word8
+  , _msgGroupDelayDepA_valid  :: !Word8
     -- ^ bit-field indicating validity of the values, LSB indicating tgd validity
     -- etc. 1 = value is valid, 0 = value is not valid.
-  , _msgGroupDelayDepA_tgd    :: Int16
-  , _msgGroupDelayDepA_isc_l1ca :: Int16
-  , _msgGroupDelayDepA_isc_l2c :: Int16
+  , _msgGroupDelayDepA_tgd    :: !Int16
+  , _msgGroupDelayDepA_isc_l1ca :: !Int16
+  , _msgGroupDelayDepA_isc_l2c :: !Int16
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgGroupDelayDepA where
@@ -1785,16 +1789,16 @@
 --
 -- Please see ICD-GPS-200 (30.3.3.3.1.1) for more details.
 data MsgGroupDelay = MsgGroupDelay
-  { _msgGroupDelay_t_op   :: GpsTimeSec
+  { _msgGroupDelay_t_op   :: !GpsTimeSec
     -- ^ Data Predict Time of Week
-  , _msgGroupDelay_sid    :: GnssSignal
+  , _msgGroupDelay_sid    :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _msgGroupDelay_valid  :: Word8
+  , _msgGroupDelay_valid  :: !Word8
     -- ^ bit-field indicating validity of the values, LSB indicating tgd validity
     -- etc. 1 = value is valid, 0 = value is not valid.
-  , _msgGroupDelay_tgd    :: Int16
-  , _msgGroupDelay_isc_l1ca :: Int16
-  , _msgGroupDelay_isc_l2c :: Int16
+  , _msgGroupDelay_tgd    :: !Int16
+  , _msgGroupDelay_isc_l1ca :: !Int16
+  , _msgGroupDelay_isc_l2c :: !Int16
   } deriving ( Show, Read, Eq )
 
 instance Binary MsgGroupDelay where
@@ -1822,17 +1826,17 @@
 $(makeLenses ''MsgGroupDelay)
 
 data AlmanacCommonContent = AlmanacCommonContent
-  { _almanacCommonContent_sid        :: GnssSignal
+  { _almanacCommonContent_sid        :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _almanacCommonContent_toa        :: GpsTimeSec
+  , _almanacCommonContent_toa        :: !GpsTimeSec
     -- ^ Reference time of almanac
-  , _almanacCommonContent_ura        :: Double
+  , _almanacCommonContent_ura        :: !Double
     -- ^ User Range Accuracy
-  , _almanacCommonContent_fit_interval :: Word32
+  , _almanacCommonContent_fit_interval :: !Word32
     -- ^ Curve fit interval
-  , _almanacCommonContent_valid      :: Word8
+  , _almanacCommonContent_valid      :: !Word8
     -- ^ Status of almanac, 1 = valid, 0 = invalid
-  , _almanacCommonContent_health_bits :: Word8
+  , _almanacCommonContent_health_bits :: !Word8
     -- ^ Satellite health status for GPS:   - bits 5-7: NAV data health status.
     -- See IS-GPS-200H     Table 20-VII: NAV Data Health Indications.   - bits
     -- 0-4: Signal health status. See IS-GPS-200H     Table 20-VIII. Codes for
@@ -1876,25 +1880,25 @@
 -- Please see the Navstar GPS Space Segment/Navigation user interfaces (ICD-
 -- GPS-200, Chapter 20.3.3.5.1.2 Almanac Data) for more details.
 data MsgAlmanacGps = MsgAlmanacGps
-  { _msgAlmanacGps_common :: AlmanacCommonContent
+  { _msgAlmanacGps_common :: !AlmanacCommonContent
     -- ^ Values common for all almanac types
-  , _msgAlmanacGps_m0     :: Double
+  , _msgAlmanacGps_m0     :: !Double
     -- ^ Mean anomaly at reference time
-  , _msgAlmanacGps_ecc    :: Double
+  , _msgAlmanacGps_ecc    :: !Double
     -- ^ Eccentricity of satellite orbit
-  , _msgAlmanacGps_sqrta  :: Double
+  , _msgAlmanacGps_sqrta  :: !Double
     -- ^ Square root of the semi-major axis of orbit
-  , _msgAlmanacGps_omega0 :: Double
+  , _msgAlmanacGps_omega0 :: !Double
     -- ^ Longitude of ascending node of orbit plane at weekly epoch
-  , _msgAlmanacGps_omegadot :: Double
+  , _msgAlmanacGps_omegadot :: !Double
     -- ^ Rate of right ascension
-  , _msgAlmanacGps_w      :: Double
+  , _msgAlmanacGps_w      :: !Double
     -- ^ Argument of perigee
-  , _msgAlmanacGps_inc    :: Double
+  , _msgAlmanacGps_inc    :: !Double
     -- ^ Inclination
-  , _msgAlmanacGps_af0    :: Double
+  , _msgAlmanacGps_af0    :: !Double
     -- ^ Polynomial clock correction coefficient (clock bias)
-  , _msgAlmanacGps_af1    :: Double
+  , _msgAlmanacGps_af1    :: !Double
     -- ^ Polynomial clock correction coefficient (clock drift)
   } deriving ( Show, Read, Eq )
 
@@ -1940,22 +1944,22 @@
 -- Please see the GLO ICD 5.1 "Chapter 4.5 Non-immediate information and
 -- almanac" for details.
 data MsgAlmanacGlo = MsgAlmanacGlo
-  { _msgAlmanacGlo_common    :: AlmanacCommonContent
+  { _msgAlmanacGlo_common    :: !AlmanacCommonContent
     -- ^ Values common for all almanac types
-  , _msgAlmanacGlo_lambda_na :: Double
+  , _msgAlmanacGlo_lambda_na :: !Double
     -- ^ Longitude of the first ascending node of the orbit in PZ-90.02
     -- coordinate system
-  , _msgAlmanacGlo_t_lambda_na :: Double
+  , _msgAlmanacGlo_t_lambda_na :: !Double
     -- ^ Time of the first ascending node passage
-  , _msgAlmanacGlo_i         :: Double
+  , _msgAlmanacGlo_i         :: !Double
     -- ^ Value of inclination at instant of t_lambda
-  , _msgAlmanacGlo_t         :: Double
+  , _msgAlmanacGlo_t         :: !Double
     -- ^ Value of Draconian period at instant of t_lambda
-  , _msgAlmanacGlo_t_dot     :: Double
+  , _msgAlmanacGlo_t_dot     :: !Double
     -- ^ Rate of change of the Draconian period
-  , _msgAlmanacGlo_epsilon   :: Double
+  , _msgAlmanacGlo_epsilon   :: !Double
     -- ^ Eccentricity at instant of t_lambda
-  , _msgAlmanacGlo_omega     :: Double
+  , _msgAlmanacGlo_omega     :: !Double
     -- ^ Argument of perigee at instant of t_lambda
   } deriving ( Show, Read, Eq )
 
@@ -1998,11 +2002,11 @@
 -- ... 28                       FCN for SV orbital slot 28 29
 -- 0xFF 30                       0xFF 31                       0xFF
 data MsgFcnsGlo = MsgFcnsGlo
-  { _msgFcnsGlo_wn   :: Word16
+  { _msgFcnsGlo_wn   :: !Word16
     -- ^ GPS Week number
-  , _msgFcnsGlo_tow_ms :: Word32
+  , _msgFcnsGlo_tow_ms :: !Word32
     -- ^ GPS Time of week
-  , _msgFcnsGlo_fcns :: [Word8]
+  , _msgFcnsGlo_fcns :: ![Word8]
     -- ^ GLONASS fequency number per orbital slot
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Piksi.hs b/src/SwiftNav/SBP/Piksi.hs
--- a/src/SwiftNav/SBP/Piksi.hs
+++ b/src/SwiftNav/SBP/Piksi.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Piksi
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -83,7 +87,7 @@
 --
 -- This message from the host resets the Piksi back into the bootloader.
 data MsgReset = MsgReset
-  { _msgReset_flags :: Word32
+  { _msgReset_flags :: !Word32
     -- ^ Reset flags
   } deriving ( Show, Read, Eq )
 
@@ -179,7 +183,7 @@
 -- This message resets either the DGNSS Kalman filters or Integer Ambiguity
 -- Resolution (IAR) process.
 data MsgResetFilters = MsgResetFilters
-  { _msgResetFilters_filter :: Word8
+  { _msgResetFilters_filter :: !Word8
     -- ^ Filter flags
   } deriving ( Show, Read, Eq )
 
@@ -231,12 +235,12 @@
 -- (RTOS) thread usage statistics for the named thread. The reported percentage
 -- values must be normalized.
 data MsgThreadState = MsgThreadState
-  { _msgThreadState_name     :: Text
+  { _msgThreadState_name     :: !Text
     -- ^ Thread name (NULL terminated)
-  , _msgThreadState_cpu      :: Word16
+  , _msgThreadState_cpu      :: !Word16
     -- ^ Percentage cpu use for this thread. Values range from 0 - 1000 and needs
     -- to be renormalized to 100
-  , _msgThreadState_stack_free :: Word32
+  , _msgThreadState_stack_free :: !Word32
     -- ^ Free stack space for this thread
   } deriving ( Show, Read, Eq )
 
@@ -263,17 +267,17 @@
 -- Throughput, utilization, and error counts on the RX/TX buffers of this UART
 -- channel. The reported percentage values must be normalized.
 data UARTChannel = UARTChannel
-  { _uARTChannel_tx_throughput :: Float
+  { _uARTChannel_tx_throughput :: !Float
     -- ^ UART transmit throughput
-  , _uARTChannel_rx_throughput :: Float
+  , _uARTChannel_rx_throughput :: !Float
     -- ^ UART receive throughput
-  , _uARTChannel_crc_error_count :: Word16
+  , _uARTChannel_crc_error_count :: !Word16
     -- ^ UART CRC error count
-  , _uARTChannel_io_error_count :: Word16
+  , _uARTChannel_io_error_count :: !Word16
     -- ^ UART IO error count
-  , _uARTChannel_tx_buffer_level :: Word8
+  , _uARTChannel_tx_buffer_level :: !Word8
     -- ^ UART transmit buffer percentage utilization (ranges from 0 to 255)
-  , _uARTChannel_rx_buffer_level :: Word8
+  , _uARTChannel_rx_buffer_level :: !Word8
     -- ^ UART receive buffer percentage utilization (ranges from 0 to 255)
   } deriving ( Show, Read, Eq )
 
@@ -306,13 +310,13 @@
 -- for link quality as incomplete or missing sets will increase the period.
 -- Long periods can cause momentary RTK solution outages.
 data Period = Period
-  { _period_avg   :: Int32
+  { _period_avg   :: !Int32
     -- ^ Average period
-  , _period_pmin  :: Int32
+  , _period_pmin  :: !Int32
     -- ^ Minimum period
-  , _period_pmax  :: Int32
+  , _period_pmax  :: !Int32
     -- ^ Maximum period
-  , _period_current :: Int32
+  , _period_current :: !Int32
     -- ^ Smoothed estimate of the current period
   } deriving ( Show, Read, Eq )
 
@@ -340,13 +344,13 @@
 -- GPS time calculated locally by the receiver to give a precise measurement of
 -- the end-to-end communication latency in the system.
 data Latency = Latency
-  { _latency_avg   :: Int32
+  { _latency_avg   :: !Int32
     -- ^ Average latency
-  , _latency_lmin  :: Int32
+  , _latency_lmin  :: !Int32
     -- ^ Minimum latency
-  , _latency_lmax  :: Int32
+  , _latency_lmax  :: !Int32
     -- ^ Maximum latency
-  , _latency_current :: Int32
+  , _latency_current :: !Int32
     -- ^ Smoothed estimate of the current latency
   } deriving ( Show, Read, Eq )
 
@@ -381,15 +385,15 @@
 -- received base observations while the period indicates their likelihood of
 -- transmission.
 data MsgUartState = MsgUartState
-  { _msgUartState_uart_a   :: UARTChannel
+  { _msgUartState_uart_a   :: !UARTChannel
     -- ^ State of UART A
-  , _msgUartState_uart_b   :: UARTChannel
+  , _msgUartState_uart_b   :: !UARTChannel
     -- ^ State of UART B
-  , _msgUartState_uart_ftdi :: UARTChannel
+  , _msgUartState_uart_ftdi :: !UARTChannel
     -- ^ State of UART FTDI (USB logger)
-  , _msgUartState_latency  :: Latency
+  , _msgUartState_latency  :: !Latency
     -- ^ UART communication latency
-  , _msgUartState_obs_period :: Period
+  , _msgUartState_obs_period :: !Period
     -- ^ Observation receipt period
   } deriving ( Show, Read, Eq )
 
@@ -422,13 +426,13 @@
 --
 -- Deprecated
 data MsgUartStateDepa = MsgUartStateDepa
-  { _msgUartStateDepa_uart_a  :: UARTChannel
+  { _msgUartStateDepa_uart_a  :: !UARTChannel
     -- ^ State of UART A
-  , _msgUartStateDepa_uart_b  :: UARTChannel
+  , _msgUartStateDepa_uart_b  :: !UARTChannel
     -- ^ State of UART B
-  , _msgUartStateDepa_uart_ftdi :: UARTChannel
+  , _msgUartStateDepa_uart_ftdi :: !UARTChannel
     -- ^ State of UART FTDI (USB logger)
-  , _msgUartStateDepa_latency :: Latency
+  , _msgUartStateDepa_latency :: !Latency
     -- ^ UART communication latency
   } deriving ( Show, Read, Eq )
 
@@ -461,7 +465,7 @@
 -- process, which resolves unknown integer ambiguities from double-differenced
 -- carrier-phase measurements from satellite observations.
 data MsgIarState = MsgIarState
-  { _msgIarState_num_hyps :: Word32
+  { _msgIarState_num_hyps :: !Word32
     -- ^ Number of integer ambiguity hypotheses remaining
   } deriving ( Show, Read, Eq )
 
@@ -487,9 +491,9 @@
 -- This message allows setting a mask to prevent a particular satellite from
 -- being used in various Piksi subsystems.
 data MsgMaskSatellite = MsgMaskSatellite
-  { _msgMaskSatellite_mask :: Word8
+  { _msgMaskSatellite_mask :: !Word8
     -- ^ Mask of systems that should ignore this satellite.
-  , _msgMaskSatellite_sid :: GnssSignal
+  , _msgMaskSatellite_sid :: !GnssSignal
     -- ^ GNSS signal for which the mask is applied
   } deriving ( Show, Read, Eq )
 
@@ -518,15 +522,15 @@
 -- processor's monitoring system and the RF frontend die temperature if
 -- available.
 data MsgDeviceMonitor = MsgDeviceMonitor
-  { _msgDeviceMonitor_dev_vin       :: Int16
+  { _msgDeviceMonitor_dev_vin       :: !Int16
     -- ^ Device V_in
-  , _msgDeviceMonitor_cpu_vint      :: Int16
+  , _msgDeviceMonitor_cpu_vint      :: !Int16
     -- ^ Processor V_int
-  , _msgDeviceMonitor_cpu_vaux      :: Int16
+  , _msgDeviceMonitor_cpu_vaux      :: !Int16
     -- ^ Processor V_aux
-  , _msgDeviceMonitor_cpu_temperature :: Int16
+  , _msgDeviceMonitor_cpu_temperature :: !Int16
     -- ^ Processor temperature
-  , _msgDeviceMonitor_fe_temperature :: Int16
+  , _msgDeviceMonitor_fe_temperature :: !Int16
     -- ^ Frontend temperature (if available)
   } deriving ( Show, Read, Eq )
 
@@ -560,9 +564,9 @@
 -- Request the recipient to execute an command. Output will be sent in MSG_LOG
 -- messages, and the exit code will be returned with MSG_COMMAND_RESP.
 data MsgCommandReq = MsgCommandReq
-  { _msgCommandReq_sequence :: Word32
+  { _msgCommandReq_sequence :: !Word32
     -- ^ Sequence number
-  , _msgCommandReq_command :: Text
+  , _msgCommandReq_command :: !Text
     -- ^ Command line to execute
   } deriving ( Show, Read, Eq )
 
@@ -590,9 +594,9 @@
 -- The response to MSG_COMMAND_REQ with the return code of the command.  A
 -- return code of zero indicates success.
 data MsgCommandResp = MsgCommandResp
-  { _msgCommandResp_sequence :: Word32
+  { _msgCommandResp_sequence :: !Word32
     -- ^ Sequence number
-  , _msgCommandResp_code   :: Int32
+  , _msgCommandResp_code   :: !Int32
     -- ^ Exit code
   } deriving ( Show, Read, Eq )
 
@@ -621,9 +625,9 @@
 -- MSG_COMMAND_REQ. The sequence number can be used to filter for filtering the
 -- correct command.
 data MsgCommandOutput = MsgCommandOutput
-  { _msgCommandOutput_sequence :: Word32
+  { _msgCommandOutput_sequence :: !Word32
     -- ^ Sequence number
-  , _msgCommandOutput_line   :: Text
+  , _msgCommandOutput_line   :: !Text
     -- ^ Line of standard output or standard error
   } deriving ( Show, Read, Eq )
 
@@ -674,21 +678,21 @@
 -- The state of a network interface on the Piksi. Data is made to reflect
 -- output of ifaddrs struct returned by getifaddrs in c.
 data MsgNetworkStateResp = MsgNetworkStateResp
-  { _msgNetworkStateResp_ipv4_address :: [Word8]
+  { _msgNetworkStateResp_ipv4_address :: ![Word8]
     -- ^ IPv4 address (all zero when unavailable)
-  , _msgNetworkStateResp_ipv4_mask_size :: Word8
+  , _msgNetworkStateResp_ipv4_mask_size :: !Word8
     -- ^ IPv4 netmask CIDR notation
-  , _msgNetworkStateResp_ipv6_address :: [Word8]
+  , _msgNetworkStateResp_ipv6_address :: ![Word8]
     -- ^ IPv6 address (all zero when unavailable)
-  , _msgNetworkStateResp_ipv6_mask_size :: Word8
+  , _msgNetworkStateResp_ipv6_mask_size :: !Word8
     -- ^ IPv6 netmask CIDR notation
-  , _msgNetworkStateResp_rx_bytes     :: Word32
+  , _msgNetworkStateResp_rx_bytes     :: !Word32
     -- ^ Number of Rx bytes
-  , _msgNetworkStateResp_tx_bytes     :: Word32
+  , _msgNetworkStateResp_tx_bytes     :: !Word32
     -- ^ Number of Tx bytes
-  , _msgNetworkStateResp_interface_name :: Text
+  , _msgNetworkStateResp_interface_name :: !Text
     -- ^ Interface Name
-  , _msgNetworkStateResp_flags        :: Word32
+  , _msgNetworkStateResp_flags        :: !Word32
     -- ^ Interface flags from SIOCGIFFLAGS
   } deriving ( Show, Read, Eq )
 
@@ -727,19 +731,19 @@
 --
 -- Spectrum analyzer packet.
 data MsgSpecan = MsgSpecan
-  { _msgSpecan_channel_tag   :: Word16
+  { _msgSpecan_channel_tag   :: !Word16
     -- ^ Channel ID
-  , _msgSpecan_t             :: GpsTime
+  , _msgSpecan_t             :: !GpsTime
     -- ^ Receiver time of this observation
-  , _msgSpecan_freq_ref      :: Float
+  , _msgSpecan_freq_ref      :: !Float
     -- ^ Reference frequency of this packet
-  , _msgSpecan_freq_step     :: Float
+  , _msgSpecan_freq_step     :: !Float
     -- ^ Frequency step of points in this packet
-  , _msgSpecan_amplitude_ref :: Float
+  , _msgSpecan_amplitude_ref :: !Float
     -- ^ Reference amplitude of this packet
-  , _msgSpecan_amplitude_unit :: Float
+  , _msgSpecan_amplitude_unit :: !Float
     -- ^ Amplitude unit value of points in this packet
-  , _msgSpecan_amplitude_value :: [Word8]
+  , _msgSpecan_amplitude_value :: ![Word8]
     -- ^ Amplitude values (in the above units) of points in this packet
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Settings.hs b/src/SwiftNav/SBP/Settings.hs
--- a/src/SwiftNav/SBP/Settings.hs
+++ b/src/SwiftNav/SBP/Settings.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Settings
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -61,7 +65,7 @@
 --
 -- The setting message writes the device configuration.
 data MsgSettingsWrite = MsgSettingsWrite
-  { _msgSettingsWrite_setting :: Text
+  { _msgSettingsWrite_setting :: !Text
     -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
     -- SETTING, VALUE]. A device will only process to this message when it is
     -- received from sender ID 0x42.
@@ -88,7 +92,7 @@
 --
 -- The setting message reads the device configuration.
 data MsgSettingsReadReq = MsgSettingsReadReq
-  { _msgSettingsReadReq_setting :: Text
+  { _msgSettingsReadReq_setting :: !Text
     -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
     -- SETTING]. A device will only respond to this message when it is received
     -- from sender ID 0x42.
@@ -115,7 +119,7 @@
 --
 -- The setting message reads the device configuration.
 data MsgSettingsReadResp = MsgSettingsReadResp
-  { _msgSettingsReadResp_setting :: Text
+  { _msgSettingsReadResp_setting :: !Text
     -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
     -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
@@ -144,7 +148,7 @@
 -- with contents [SECTION_SETTING, SETTING, VALUE]. A device will only respond
 -- to this message when it is received from sender ID 0x42.
 data MsgSettingsReadByIndexReq = MsgSettingsReadByIndexReq
-  { _msgSettingsReadByIndexReq_index :: Word16
+  { _msgSettingsReadByIndexReq_index :: !Word16
     -- ^ An index into the device settings, with values ranging from 0 to
     -- length(settings)
   } deriving ( Show, Read, Eq )
@@ -172,10 +176,10 @@
 -- the setting at an index, returning a NULL-terminated and delimited string
 -- with contents [SECTION_SETTING, SETTING, VALUE].
 data MsgSettingsReadByIndexResp = MsgSettingsReadByIndexResp
-  { _msgSettingsReadByIndexResp_index :: Word16
+  { _msgSettingsReadByIndexResp_index :: !Word16
     -- ^ An index into the device settings, with values ranging from 0 to
     -- length(settings)
-  , _msgSettingsReadByIndexResp_setting :: Text
+  , _msgSettingsReadByIndexResp_setting :: !Text
     -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
     -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
@@ -227,7 +231,7 @@
 -- settings daemon.  The host should reply with MSG_SETTINGS_WRITE for this
 -- setting to set the initial value.
 data MsgSettingsRegister = MsgSettingsRegister
-  { _msgSettingsRegister_setting :: Text
+  { _msgSettingsRegister_setting :: !Text
     -- ^ A NULL-terminated and delimited string with contents [SECTION_SETTING,
     -- SETTING, VALUE].
   } deriving ( Show, Read, Eq )
diff --git a/src/SwiftNav/SBP/System.hs b/src/SwiftNav/SBP/System.hs
--- a/src/SwiftNav/SBP/System.hs
+++ b/src/SwiftNav/SBP/System.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.System
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -36,11 +40,11 @@
 -- host or other attached devices that the system has started and is now ready
 -- to respond to commands or configuration requests.
 data MsgStartup = MsgStartup
-  { _msgStartup_cause      :: Word8
+  { _msgStartup_cause      :: !Word8
     -- ^ Cause of startup
-  , _msgStartup_startup_type :: Word8
+  , _msgStartup_startup_type :: !Word8
     -- ^ Startup type
-  , _msgStartup_reserved   :: Word16
+  , _msgStartup_reserved   :: !Word16
     -- ^ Reserved
   } deriving ( Show, Read, Eq )
 
@@ -71,13 +75,13 @@
 -- corrections.  It is expected to be sent with each receipt of a complete
 -- corrections packet.
 data MsgDgnssStatus = MsgDgnssStatus
-  { _msgDgnssStatus_flags     :: Word8
+  { _msgDgnssStatus_flags     :: !Word8
     -- ^ Status flags
-  , _msgDgnssStatus_latency   :: Word16
+  , _msgDgnssStatus_latency   :: !Word16
     -- ^ Latency of observation receipt
-  , _msgDgnssStatus_num_signals :: Word8
+  , _msgDgnssStatus_num_signals :: !Word8
     -- ^ Number of signals from base station
-  , _msgDgnssStatus_source    :: Text
+  , _msgDgnssStatus_source    :: !Text
     -- ^ Corrections source string
   } deriving ( Show, Read, Eq )
 
@@ -114,7 +118,7 @@
 -- indicate that an error has occurred in the system. To determine the source
 -- of the error, the remaining error flags should be inspected.
 data MsgHeartbeat = MsgHeartbeat
-  { _msgHeartbeat_flags :: Word32
+  { _msgHeartbeat_flags :: !Word32
     -- ^ Status flags
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/TH.hs b/src/SwiftNav/SBP/TH.hs
--- a/src/SwiftNav/SBP/TH.hs
+++ b/src/SwiftNav/SBP/TH.hs
@@ -1,3 +1,7 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.TH
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
diff --git a/src/SwiftNav/SBP/Tracking.hs b/src/SwiftNav/SBP/Tracking.hs
--- a/src/SwiftNav/SBP/Tracking.hs
+++ b/src/SwiftNav/SBP/Tracking.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Tracking
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -36,53 +40,53 @@
 -- The tracking message returns a set tracking channel parameters for a single
 -- tracking channel useful for debugging issues.
 data MsgTrackingStateDetailed = MsgTrackingStateDetailed
-  { _msgTrackingStateDetailed_recv_time  :: Word64
+  { _msgTrackingStateDetailed_recv_time  :: !Word64
     -- ^ Receiver clock time.
-  , _msgTrackingStateDetailed_tot        :: GpsTime
+  , _msgTrackingStateDetailed_tot        :: !GpsTime
     -- ^ Time of transmission of signal from satellite. TOW only valid when TOW
     -- status is decoded or propagated. WN only valid when week number valid
     -- flag is set.
-  , _msgTrackingStateDetailed_P          :: Word32
+  , _msgTrackingStateDetailed_P          :: !Word32
     -- ^ Pseudorange observation. Valid only when pseudorange valid flag is set.
-  , _msgTrackingStateDetailed_P_std      :: Word16
+  , _msgTrackingStateDetailed_P_std      :: !Word16
     -- ^ Pseudorange observation standard deviation. Valid only when pseudorange
     -- valid flag is set.
-  , _msgTrackingStateDetailed_L          :: CarrierPhase
+  , _msgTrackingStateDetailed_L          :: !CarrierPhase
     -- ^ Carrier phase observation with typical sign convention. Valid only when
     -- PLL pessimistic lock is achieved.
-  , _msgTrackingStateDetailed_cn0        :: Word8
+  , _msgTrackingStateDetailed_cn0        :: !Word8
     -- ^ Carrier-to-Noise density
-  , _msgTrackingStateDetailed_lock       :: Word16
+  , _msgTrackingStateDetailed_lock       :: !Word16
     -- ^ Lock time. It is encoded according to DF402 from the RTCM 10403.2
     -- Amendment 2 specification. Valid values range from 0 to 15.
-  , _msgTrackingStateDetailed_sid        :: GnssSignal
+  , _msgTrackingStateDetailed_sid        :: !GnssSignal
     -- ^ GNSS signal identifier.
-  , _msgTrackingStateDetailed_doppler    :: Int32
+  , _msgTrackingStateDetailed_doppler    :: !Int32
     -- ^ Carrier Doppler frequency.
-  , _msgTrackingStateDetailed_doppler_std :: Word16
+  , _msgTrackingStateDetailed_doppler_std :: !Word16
     -- ^ Carrier Doppler frequency standard deviation.
-  , _msgTrackingStateDetailed_uptime     :: Word32
+  , _msgTrackingStateDetailed_uptime     :: !Word32
     -- ^ Number of seconds of continuous tracking. Specifies how much time signal
     -- is in continuous track.
-  , _msgTrackingStateDetailed_clock_offset :: Int16
+  , _msgTrackingStateDetailed_clock_offset :: !Int16
     -- ^ TCXO clock offset. Valid only when valid clock valid flag is set.
-  , _msgTrackingStateDetailed_clock_drift :: Int16
+  , _msgTrackingStateDetailed_clock_drift :: !Int16
     -- ^ TCXO clock drift. Valid only when valid clock valid flag is set.
-  , _msgTrackingStateDetailed_corr_spacing :: Word16
+  , _msgTrackingStateDetailed_corr_spacing :: !Word16
     -- ^ Early-Prompt (EP) and Prompt-Late (PL) correlators spacing.
-  , _msgTrackingStateDetailed_acceleration :: Int8
+  , _msgTrackingStateDetailed_acceleration :: !Int8
     -- ^ Acceleration. Valid only when acceleration valid flag is set.
-  , _msgTrackingStateDetailed_sync_flags :: Word8
+  , _msgTrackingStateDetailed_sync_flags :: !Word8
     -- ^ Synchronization status flags.
-  , _msgTrackingStateDetailed_tow_flags  :: Word8
+  , _msgTrackingStateDetailed_tow_flags  :: !Word8
     -- ^ TOW status flags.
-  , _msgTrackingStateDetailed_track_flags :: Word8
+  , _msgTrackingStateDetailed_track_flags :: !Word8
     -- ^ Tracking loop status flags.
-  , _msgTrackingStateDetailed_nav_flags  :: Word8
+  , _msgTrackingStateDetailed_nav_flags  :: !Word8
     -- ^ Navigation data status flags.
-  , _msgTrackingStateDetailed_pset_flags :: Word8
+  , _msgTrackingStateDetailed_pset_flags :: !Word8
     -- ^ Parameters sets flags.
-  , _msgTrackingStateDetailed_misc_flags :: Word8
+  , _msgTrackingStateDetailed_misc_flags :: !Word8
     -- ^ Miscellaneous flags.
   } deriving ( Show, Read, Eq )
 
@@ -145,11 +149,11 @@
 -- Tracking channel state for a specific satellite signal and measured signal
 -- power.
 data TrackingChannelState = TrackingChannelState
-  { _trackingChannelState_sid :: GnssSignal16
+  { _trackingChannelState_sid :: !GnssSignal16
     -- ^ GNSS signal being tracked
-  , _trackingChannelState_fcn :: Word8
+  , _trackingChannelState_fcn :: !Word8
     -- ^ Frequency channel number (GLONASS only)
-  , _trackingChannelState_cn0 :: Word8
+  , _trackingChannelState_cn0 :: !Word8
     -- ^ Carrier-to-Noise density.  Zero implies invalid cn0.
   } deriving ( Show, Read, Eq )
 
@@ -177,7 +181,7 @@
 -- states. It reports status and carrier-to-noise density measurements for all
 -- tracked satellites.
 data MsgTrackingState = MsgTrackingState
-  { _msgTrackingState_states :: [TrackingChannelState]
+  { _msgTrackingState_states :: ![TrackingChannelState]
     -- ^ Signal tracking channel state
   } deriving ( Show, Read, Eq )
 
@@ -199,9 +203,9 @@
 --
 -- Structure containing in-phase and quadrature correlation components.
 data TrackingChannelCorrelation = TrackingChannelCorrelation
-  { _trackingChannelCorrelation_I :: Int32
+  { _trackingChannelCorrelation_I :: !Int32
     -- ^ In-phase correlation
-  , _trackingChannelCorrelation_Q :: Int32
+  , _trackingChannelCorrelation_Q :: !Int32
     -- ^ Quadrature correlation
   } deriving ( Show, Read, Eq )
 
@@ -226,11 +230,11 @@
 -- When enabled, a tracking channel can output the correlations at each update
 -- interval.
 data MsgTrackingIq = MsgTrackingIq
-  { _msgTrackingIq_channel :: Word8
+  { _msgTrackingIq_channel :: !Word8
     -- ^ Tracking channel of origin
-  , _msgTrackingIq_sid   :: GnssSignal
+  , _msgTrackingIq_sid   :: !GnssSignal
     -- ^ GNSS signal identifier
-  , _msgTrackingIq_corrs :: [TrackingChannelCorrelation]
+  , _msgTrackingIq_corrs :: ![TrackingChannelCorrelation]
     -- ^ Early, Prompt and Late correlations
   } deriving ( Show, Read, Eq )
 
@@ -256,11 +260,11 @@
 --
 -- Deprecated.
 data TrackingChannelStateDepA = TrackingChannelStateDepA
-  { _trackingChannelStateDepA_state :: Word8
+  { _trackingChannelStateDepA_state :: !Word8
     -- ^ Status of tracking channel
-  , _trackingChannelStateDepA_prn :: Word8
+  , _trackingChannelStateDepA_prn :: !Word8
     -- ^ PRN-1 being tracked
-  , _trackingChannelStateDepA_cn0 :: Float
+  , _trackingChannelStateDepA_cn0 :: !Float
     -- ^ Carrier-to-noise density
   } deriving ( Show, Read, Eq )
 
@@ -286,7 +290,7 @@
 --
 -- Deprecated.
 data MsgTrackingStateDepA = MsgTrackingStateDepA
-  { _msgTrackingStateDepA_states :: [TrackingChannelStateDepA]
+  { _msgTrackingStateDepA_states :: ![TrackingChannelStateDepA]
     -- ^ Satellite tracking channel state
   } deriving ( Show, Read, Eq )
 
@@ -308,11 +312,11 @@
 --
 -- Deprecated.
 data TrackingChannelStateDepB = TrackingChannelStateDepB
-  { _trackingChannelStateDepB_state :: Word8
+  { _trackingChannelStateDepB_state :: !Word8
     -- ^ Status of tracking channel
-  , _trackingChannelStateDepB_sid :: GnssSignal
+  , _trackingChannelStateDepB_sid :: !GnssSignal
     -- ^ GNSS signal being tracked
-  , _trackingChannelStateDepB_cn0 :: Float
+  , _trackingChannelStateDepB_cn0 :: !Float
     -- ^ Carrier-to-noise density
   } deriving ( Show, Read, Eq )
 
@@ -338,7 +342,7 @@
 --
 -- Deprecated.
 data MsgTrackingStateDepB = MsgTrackingStateDepB
-  { _msgTrackingStateDepB_states :: [TrackingChannelStateDepB]
+  { _msgTrackingStateDepB_states :: ![TrackingChannelStateDepB]
     -- ^ Signal tracking channel state
   } deriving ( Show, Read, Eq )
 
diff --git a/src/SwiftNav/SBP/Types.hs b/src/SwiftNav/SBP/Types.hs
--- a/src/SwiftNav/SBP/Types.hs
+++ b/src/SwiftNav/SBP/Types.hs
@@ -1,3 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE OverloadedStrings #-}
+
 -- |
 -- Module:      SwiftNav.SBP.Types
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -39,19 +44,19 @@
 -- messages, as well as receive messages from the host operating
 -- system.
 data Msg = Msg
-  { _msgSBPType    :: Word16
+  { _msgSBPType    :: !Word16
     -- ^ Uniquely identifies the type of the payload contents
-  , _msgSBPSender  :: Word16
+  , _msgSBPSender  :: !Word16
     -- ^ A unique identifier of the sending hardware. For v1.0,
     -- set to the 2 least significant bytes of the device serial
     -- number
-  , _msgSBPLen     :: Word8
+  , _msgSBPLen     :: !Word8
     -- ^ Byte-length of the payload field
   , _msgSBPPayload :: !ByteString
     -- ^ Binary data of the message, as identified by Message Type and
     -- Length. Usually contains the in-memory binary representation of
     -- a C struct (see documentation on individual message types)
-  , _msgSBPCrc     :: Word16
+  , _msgSBPCrc     :: !Word16
     -- ^ Cyclic Redundancy Check (CRC) of the packet's binary data from
     -- the Message Type up to the end of Payload (does not include the
     -- Preamble)
diff --git a/src/SwiftNav/SBP/User.hs b/src/SwiftNav/SBP/User.hs
--- a/src/SwiftNav/SBP/User.hs
+++ b/src/SwiftNav/SBP/User.hs
@@ -1,4 +1,8 @@
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE NoImplicitPrelude           #-}
+{-# LANGUAGE TemplateHaskell             #-}
+{-# LANGUAGE RecordWildCards             #-}
+
 -- |
 -- Module:      SwiftNav.SBP.User
 -- Copyright:   Copyright (C) 2015 Swift Navigation, Inc.
@@ -35,7 +39,7 @@
 -- This message can contain any application specific user data up to a maximum
 -- length of 255 bytes per message.
 data MsgUserData = MsgUserData
-  { _msgUserData_contents :: [Word8]
+  { _msgUserData_contents :: ![Word8]
     -- ^ User data payload
   } deriving ( Show, Read, Eq )
 
diff --git a/test/Test/SwiftNav/CRC16.hs b/test/Test/SwiftNav/CRC16.hs
--- a/test/Test/SwiftNav/CRC16.hs
+++ b/test/Test/SwiftNav/CRC16.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+
 module Test.SwiftNav.CRC16
   ( tests
   ) where
diff --git a/test/Test/SwiftNav/SBP/Encoding.hs b/test/Test/SwiftNav/SBP/Encoding.hs
--- a/test/Test/SwiftNav/SBP/Encoding.hs
+++ b/test/Test/SwiftNav/SBP/Encoding.hs
@@ -1,4 +1,6 @@
-{-# OPTIONS -fno-warn-orphans #-}
+{-# OPTIONS -fno-warn-orphans  #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 module Test.SwiftNav.SBP.Encoding
   ( tests
