Text.ParserCombinators.ReadP badly needs eta-expansion
Looking through some generated Core for Text.Read.Lex
(for example lexHexOct
) revealed that ReadP
is almost never eta-expanded:
$wlexHexOct_r5XJ :: forall {b}.
(Lexeme -> Text.ParserCombinators.ReadP.P b)
-> Char -> Text.ParserCombinators.ReadP.P b
[GblId, Arity=2, Str=<U><SP(SU)>, Unf=OtherCon []]
$wlexHexOct_r5XJ
= \ (@b_s4mE)
(w_s4mF :: Lexeme -> Text.ParserCombinators.ReadP.P b_s4mE)
(eta_B0 :: Char) ->
case eta_B0 of { C# y_a2vO ->
case y_a2vO of {
__DEFAULT -> Text.ParserCombinators.ReadP.Fail @b_s4mE;
'0'# ->
let {
lvl127_s4Vf :: Digits -> Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Arity=1, Str=<U>, Unf=OtherCon []]
lvl127_s4Vf
= \ (a1_Xk :: Digits) ->
w_s4mF
(Text.Read.Lex.Number
(Text.Read.Lex.MkNumber lvl5_r5X1 a1_Xk)) } in
let {
lvl128_s4Vg :: String -> Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Unf=OtherCon []]
lvl128_s4Vg = $wlexDigits_r5XI lvl5_r5X1 @b_s4mE lvl127_s4Vf } in
let {
lvl129_s4NC :: Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Unf=OtherCon []]
lvl129_s4NC
= Text.ParserCombinators.ReadP.Look @b_s4mE lvl128_s4Vg } in
let {
lvl130_s4Vh :: Digits -> Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Arity=1, Str=<U>, Unf=OtherCon []]
lvl130_s4Vh
= \ (a1_Xk :: Digits) ->
w_s4mF
(Text.Read.Lex.Number
(Text.Read.Lex.MkNumber lvl4_r5X0 a1_Xk)) } in
let {
lvl131_s4Vi :: String -> Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Unf=OtherCon []]
lvl131_s4Vi = $wlexDigits_r5XI lvl4_r5X0 @b_s4mE lvl130_s4Vh } in
let {
lvl132_s4Nz :: Text.ParserCombinators.ReadP.P b_s4mE
[LclId, Unf=OtherCon []]
lvl132_s4Nz
= Text.ParserCombinators.ReadP.Look @b_s4mE lvl131_s4Vi } in
Text.ParserCombinators.ReadP.Get
@b_s4mE
(\ (eta1_Xj :: Char) ->
case eta1_Xj of { C# ds_d29y ->
case ds_d29y of {
__DEFAULT -> Text.ParserCombinators.ReadP.Fail @b_s4mE;
'O'# -> lvl132_s4Nz;
'X'# -> lvl129_s4NC;
'o'# -> lvl132_s4Nz;
'x'# -> lvl129_s4NC
}
})
}
}
This is all due to the CPS encoding. lexDigits
there is properly eta-expanded, but for some reason usage analysis can't figure out that the passed continuation is always called with one argument. Chaos! I imagine this is also true for any other module employing ReadP
.
This could be fixed by employing the one-shot monad trick.