Global ImplicitParams technique doesn't work with optimizations enabled
Summary
When using the Global Implicit Parameters technique described in this blog post with optimizations, I observe that it doesn't work. Specifically, the global parameter is applied always, even when I override it locally. The following test:
describe "Colour disabling works" $ do
it "Disable yellow" $
let ?colourMode = DisableColour
in yellow @Text `shouldBe` ""
doesn't pass with the following error:
test/Test/Colourista.hs:44:16:
1) Colourista tests, Colour disabling works, Disable yellow
expected: ""
but got: "\ESC[93m"
Specifically, I'm trying to use ImplicitParams
to implement colour disabling and enabling in the colourista library. See the following PRs for implementation:
- Implementation: https://github.com/kowainik/colourista/pull/38
- Tests: https://github.com/kowainik/colourista/pull/43
In short, the implementation looks like this:
data ColourMode
= DisableColour
| EnableColour
deriving stock (Show, Eq, Enum, Bounded)
instance IP "colourMode" ColourMode where
ip = EnableColour
type HasColourMode = (?colourMode :: ColourMode)
withColourMode :: (HasColourMode, IsString str) => str -> str
withColourMode str = case ?colourMode of
EnableColour -> str
DisableColour -> ""
{-# INLINE withColourMode #-}
-- | Code to apply 'Yellow' colouring for the terminal output.
yellow :: (HasColourMode, IsString str) => str
yellow = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Yellow]
{-# SPECIALIZE yellow :: HasColourMode => String #-}
{-# SPECIALIZE yellow :: HasColourMode => Text #-}
{-# SPECIALIZE yellow :: HasColourMode => ByteString #-}
However, this implementation only works when I build the project with -O0
. Morever, I see the following warnings, which emitted only when I build the project without -O0
:
src/Colourista/Pure.hs:92:1: warning: [-Wredundant-constraints]
• Redundant constraint: HasColourMode
• In the type signature for:
red :: HasColourMode => String
In the SPECIALISE pragma
{-# SPECIALIZE red :: HasColourMode => String #-}
|
92 | {-# SPECIALIZE red :: HasColourMode => String #-}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/Colourista/Pure.hs:92:1: warning:
Forall'd constraint ‘HasColourMode’ is not bound in RULE lhs
Orig bndrs: [$dIP_a7Qk]
Orig lhs: let {
$dIsString_a7Qn :: IsString String
[LclId]
$dIsString_a7Qn = $dIsString_a7vq } in
let {
$dIP_a7Qm :: HasColourMode
[LclId]
$dIP_a7Qm = Colourista.Mode.$fIP"colourMode"ColourMode } in
red @ String $dIP_a7Qm $dIsString_a7Qn
optimised lhs: red @ String $dIP_a7Qm $dIsString_a7Qn
|
92 | {-# SPECIALIZE red :: HasColourMode => String #-}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Steps to reproduce
- Clone the colourista repository.
- Checkout to branch
chshersh/41-Add-some-tests
- Run tests:
cabal test --enable-tests --test-show-details=direct
Expected behavior
Tests are passing.
Environment
- GHC-8.8.3. But the error is reproducible with any GHC version.
Optional:
- Operating System: Ubuntu
- System Architecture: x86_64