Skip to content

Commit

Permalink
Avoid -Wx-partial warnings in Data.Data.Lens's doctests
Browse files Browse the repository at this point in the history
Some doctests in `Data.Data.Lens` use the partial `head` and `tail` functions,
which now produce `-Wx-partial` warnings (implied by `-Wall`) as of GHC 9.8.
Moreover, some of these doctests _rely_ on `head`/`tail` being partial, so it's
not entirely straightforward to change them. To accommodate this, we redefine
the `head`/`tail` functions (see the new `Control.Lens.Internal.Doctest`
module) so that they can be used in the doctests without triggering any
warnings. The end result should be indistinguishable to readers of the
Haddocks.
  • Loading branch information
RyanGlScott committed Aug 24, 2023
1 parent 3a7db7e commit dfbd591
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
1 change: 1 addition & 0 deletions lens.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ library
Control.Lens.Internal.Context
Control.Lens.Internal.CTypes
Control.Lens.Internal.Deque
Control.Lens.Internal.Doctest
Control.Lens.Internal.Exception
Control.Lens.Internal.FieldTH
Control.Lens.Internal.PrismTH
Expand Down
43 changes: 43 additions & 0 deletions src/Control/Lens/Internal/Doctest.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- | This module exists for the sole purpose of redefining the 'head' and 'tail'
-- functions (which are normally provided by the 'Prelude') so that they can be
-- used in the doctests of 'Data.Data.Lens'.
--
-- The 'head' and 'tail' functions are partial, and as of GHC 9.8, there is a
-- @-Wx-partial@ warning (implied by @-Wall@) that triggers any time you use
-- either of these functions. This is a fairly reasonable default in most
-- settings, but there are a handful of doctests in 'Data.Data.Lens' that do in
-- fact rely on 'head' and 'tail' being partial functions. These doctests
-- demonstrate that various functions in 'Data.Data.Lens' can recover from
-- exceptions that are thrown due to partiality (see, for instance, the @upon@
-- function).
--
-- One possible workaround would be to disable @-Wx-partial@. We don't want to
-- disable the warning for /all/ code in @lens@, however—we only want to
-- disable it for a particular group of doctests. It is rather tricky to achieve
-- this level of granularity, unfortunately. This is because tools like
-- @cabal-docspec@ rely on GHCi to work, and the statefulness of GHCi's @:set@
-- command means that disabling @-Wx-partial@ might leak into other modules'
-- doctests, which we don't want.
--
-- Instead, we opt to redefine our own versions of 'head' and 'tail' here, which
-- do not trigger any @-Wx-partial@ warnings, and use them in the
-- 'Data.Data.Lens' doctests. This has no impact on anyone reading the doctests,
-- as these functions will look indistinguishable from the 'head' and 'tail'
-- functions in the 'Prelude'. One consequence of this design is that we must
-- export the 'Control.Lens.Internal.Doctest' module, as GHCi (and therefore
-- @cabal-docspec@) won't be able to import it otherwise. Despite this technical
-- oddity, this module should be thought of as internal to @lens@.
module Control.Lens.Internal.Doctest
( head
, tail
) where

import Prelude hiding (head, tail)

head :: [a] -> a
head (x:_) = x
head [] = error "head: empty list"

tail :: [a] -> [a]
tail (_:xs) = xs
tail [] = error "tail: empty list"
2 changes: 2 additions & 0 deletions src/Data/Data/Lens.hs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ import qualified Data.Type.Equality as X
-- $setup
-- >>> :set -XNoOverloadedStrings
-- >>> import Control.Lens
-- >>> import Control.Lens.Internal.Doctest
-- >>> import Prelude hiding (head, tail)

-------------------------------------------------------------------------------
-- Generic Traversal
Expand Down

0 comments on commit dfbd591

Please sign in to comment.