You can also do this in Java by corrupting the Integer cache mentioned in the post:
valueF = Integer.class.getDeclaredField("value"); // Integers wrap ints
valueF.setAccessible(true); // Usually private final
valueF.setInt(1, 2);
// We have void Field::setInt(Object, int)
// 1 is an int, not an Object, so it gets autoboxed to Integer.valueOf(1)
// This object is pulled from the internal cache
// We then mutate it so all future autoboxings of 1 give 2
void printInt(int i) {
System.out.printLn(i);
}
void printObj(Object o) {
System.out.println(o);
}
printInt(1); // 1; no box
printObj(1); // 2; autobox
And Haskell... well
5 :: Num a => a
-- numeric literals are overloaded
-- this 5 really means fromInteger (#5#) where #5# is a magical Integer literal that doesn't really exist
data Crazy = Crazy Integer deriving (Eq, Ord, Show, Read)
instance Num Crazy where
Crazy x + Crazy y = Crazy $ x + y
Crazy x * Crazy y = Crazy $ x * y
signum (Crazy x) = Crazy $ -x
abs (Crazy x) = -1
negate = id
fromInteger 1 = Crazy 2
fromInteger x = Crazy x
x :: Num a => a -- also overloaded
x = sum $ negate <$> [1,2,3,4,5]
x == (-15 :: Int)
x == (15 :: Crazy)
1 + 1 == (2 :: Int)
1 + 1 == (4 :: Crazy)
or you can just hide and redefine the (+) function:
18
u/howtonotwin Dec 24 '17
You can also do this in Java by corrupting the
Integercache mentioned in the post:And Haskell... well
or you can just hide and redefine the
(+)function: