Skip to content
AgileLogics
5 min read

Numbers and Arithmetic

Prerequisites: Values and basic types

main :: IO ()
main = do
  print (7 + 3, 7 - 3, 7 * 3)
  print (7 / 2)
  print (7 `div` 2, 7 `mod` 2)
  print ((-7) `div` 2, (-7) `mod` 2)
  print ((-7) `quot` 2, (-7) `rem` 2)
  print (2 ^ 10, 2 ** 0.5)
  print (sqrt 16, abs (-5), negate 3)
  print (min 3 8, max 3 8)
(10,4,21)
3.5
(3,1)
(-4,1)
(-3,-1)
(1024,1.4142135623730951)
(4.0,5,-3)
(3,8)
  • / is fractional division — it always works on Double-like types.
  • div and mod are integer division and remainder; writing a function name in backticks (`div`) lets you use it between its arguments.
  • div/mod round towards negative infinity; quot/rem round towards zero (like C and Java).
  • ^ raises to a whole-number power; ** to a fractional power.
  • Negative numbers often need parentheses: abs (-5), because abs -5 means abs - 5.

Converting between number types

Haskell never converts numbers automatically. Adding an Int to a Double is a type error:

average :: [Int] -> Double
average xs = fromIntegral (sum xs) / fromIntegral (length xs)

main :: IO ()
main = do
  print (average [3, 4, 5, 6])
  print (round 2.5, round 3.5, truncate 2.7, ceiling 2.1, floor 2.9)
4.5
(2,4,2,3,2)
  • fromIntegral converts Int or Integer to any numeric type.
  • round, truncate, ceiling, and floor convert fractional numbers to integers. round uses banker's rounding: halves go to the nearest even number, so round 2.5 is 2.

Floating point

main :: IO ()
main = do
  print (0.1 + 0.2)
  print (1 / 0 :: Double)
  print (showFloat2 3.14159)
  where
    showFloat2 x = fromIntegral (round (x * 100)) / 100 :: Double
0.30000000000000004
Infinity
3.14

Double has the same rounding behavior as in every language. For exact decimal work such as money, use integers of cents or the Rational type (Data.Ratio), which stores exact fractions.

Practice

Write celsiusToF :: Double -> Double (F = C × 9 / 5 + 32) and print the result for 0, 37, and 100.

Show solution
celsiusToF :: Double -> Double
celsiusToF c = c * 9 / 5 + 32

main :: IO ()
main = do
  print (celsiusToF 0)
  print (celsiusToF 37)
  print (celsiusToF 100)
32.0
98.6
212.0