CPR analysis worker returns values the wrapper could trivially construct itself
Consider GHC.Num.Natural.naturalNegate
:
naturalNegate :: Natural -> Natural
{-# NOINLINE naturalNegate #-}
naturalNegate (NS 0##) = NS 0##
naturalNegate _ = raiseUnderflow
This will create the following WW split:
naturalNegate n = case $wnaturalNegate n of b -> NS b
$wnaturalNegate :: Natural -> Word#
{-# NOINLINE $wnaturalNegate #-}
$wnaturalNegate (NS 0##) = 0##
$wnaturalNegate _ = case raiseUnderflow of {}
but that 0##
is an expression that is both cheap to evaluate and not free in any of the parameters of the function. We could just as well construct it in the wrapper:
naturalNegate n = case $wnaturalNegate n of () -> NS 0##
$wnaturalNegate :: Natural -> ()
{-# NOINLINE $wnaturalNegate #-}
$wnaturalNegate (NS 0##) = ()
$wnaturalNegate _ = case raiseUnderflow of {}
This transformation would be completely within reach for Nested CPR; the only question is whether we want it. Maybe we should only do this for literal expressions for code size concerns.