Skip to content

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
Edited by David Feuer
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information