Implement `quot` and `rem` using `quotRem`; implement `div` and `mod` using `divMod`
If I define
myquot x y = fst (quotRem x y)
myrem x y = snd (quotRem x y)
bob :: Int -> Int -> Int
bob x y = myquot x y + myrem x y
Then I get this beautiful thing with GHC 7.9 (I ''don't'' get anything beautiful in 7.8.3, so great work, compiler gurus!):
bob :: Int -> Int -> Int
bob =
\ (w_sWx :: Int) (w1_sWy :: Int) ->
case w_sWx of _ { I# ww1_sWB ->
case w1_sWy of _ { I# ww3_sWF ->
case ww3_sWF of wild_aSo {
__DEFAULT ->
case quotRemInt# ww1_sWB wild_aSo of _ { (# ipv_aSr, ipv1_aSs #) ->
I# (+# ipv_aSr ipv1_aSs)
};
(-1) ->
case ww1_sWB of wild1_aSu {
__DEFAULT ->
case quotRemInt# wild1_aSu (-1) of _ { (# ipv_aSx, ipv1_aSy #) ->
I# (+# ipv_aSx ipv1_aSy)
};
(-9223372036854775808) -> case overflowError of wild2_00 { }
};
0 -> case divZeroError of wild1_00 { }
}
}
}
However, if I write
jones :: Int -> Int -> Int
jones x y = quot x y + rem x y
I don't get anything nice.
What I'm thinking (perhaps out of ignorance) is that we might be able to use the myquot
and myrem
definitions if it's possible to get some sort of dead code elimination to recognize when one or the other is not used, at which point it can replace the quotRemInt#
with quotInt#
or remInt#
. Then we can quit the silly quotRem
dance in user code and just write what we actually mean. Of course, exactly the same thing applies to divMod
.
Trac metadata
Trac field | Value |
---|---|
Version | 7.9 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |