-
Notifications
You must be signed in to change notification settings - Fork 4
0014: Email Tutorials Haskell For Beginners – Basic Arithmetic in Haskell and Potential Problems with Division
- 14.1. Built-in Arithmetic Operators in Haskell
- 14.2. Simple Arithmetic with
Int - 14.3. Division with
/and the “No instance for Fractional Int” Error - 14.4. Why Division with
IntIs Not Allowed by Default - 14.5. Using
Doublefor Fractional Division - 14.6. Getting an
IntResult: ThedivFunction - 14.7. Negation as a Prefix Operator
- 14.8. Exponentiation with
(^) - 14.9. Glossary of Terms for This Lesson
Haskell provides a set of built-in arithmetic operators that work much like those in other programming languages. You can perform addition, subtraction, multiplication, and division directly in expressions. These operators let you build up numeric calculations in a natural, mathematical style. However, while many operations behave as you might expect, division introduces some important subtleties related to types that beginners need to be aware of.
For operations like addition, subtraction, and multiplication, using the Int type is straightforward. You can define expressions that take two Int values and produce another Int, and the type checker is satisfied. For example, adding two integers or multiplying them yields another integer, and Haskell’s built-in operators handle this with no surprises. In these situations, your type signatures will typically involve Int, and the code compiles cleanly because all the operations are well defined for integer arithmetic.
The trouble begins when you try to use the standard division operator / with the Int type. Suppose you write code where you declare a variable d as an Int and define it as 20 / 2. In everyday arithmetic, you know that 20 / 2 equals 10, a whole number, so it feels natural to expect Haskell to accept this. Instead, the code fails to compile and the compiler reports an error along the lines of:
No instance for (Fractional Int) arising from a use of ‘/’
At this stage of learning, that error message can look intimidating. The key point to remember is that the / operator in Haskell is reserved for fractional types, and Int is not one of them. The compiler is essentially telling you that there is no way to treat Int as a fractional type for the purposes of /.
To understand why this happens, it helps to think conceptually about division. Division, by its nature, can produce fractions, not just whole numbers. In some special cases—like 20 / 2—you happen to know in advance that the result is a whole number. However, in the general case there is no way for the compiler to know that dividing two integers will always produce a whole number result. If you already knew the result ahead of time, you would not need to perform the calculation at all.
Because division generally creates fractional values, it does not make sense for the / operator to return an Int in the general case. In other languages, the compiler or runtime might silently perform rounding or implicit conversions to make such operations compile, but Haskell is strongly typed and avoids hidden conversions. Instead, Haskell insists that any fractional division use a type that genuinely supports fractional values.
The lesson explains that the / operator requires a type that belongs to a fractional class of types. While you do not yet know the full theory of type classes, you can remember a practical rule: use a fractional type such as Double with /. Double is a numeric type you already know that supports fractional values.
If you change the type of your expression from Int to Double and write something like 20 / 2 in a Double context, the code compiles and behaves as expected, yielding 10.0 as a Double. As a beginner, if you see an error mentioning “No instance for Fractional”, a good first step is to consider whether the expression should be using Double instead of Int.
There are times, however, when you know that you want an integer result. In the example of 20 / 2, you may not want a Double at all—you may specifically want an Int. For such situations, Haskell provides the div function.
The div function takes two integer arguments, performs the division, and then rounds down (floors) the result to the nearest integer. Unlike the symbolic / operator, div is written as a normal function. You use it by writing the function name followed by the two arguments, separated by spaces, for example:
div 20 2This will produce an Int result. In general, you use / when working with fractional types such as Double, and you use div when you want an integer division result that rounds down.
Another arithmetic feature discussed in the lesson is negation. In Haskell, negation is provided as a built-in prefix operator: a single dash placed in front of a number to make it negative. For example, you can write -5 to represent negative five.
In some situations, especially in more complex expressions, there can be potential ambiguity between a minus sign used for subtraction and a dash used for negation. To avoid confusion, it is often helpful to place the negated number in parentheses, such as (-5). This makes your intent clear both to the compiler and to anyone reading your code.
The final arithmetic function covered is exponentiation, which uses the caret symbol (^). This operator allows you to raise a number to a power. For example:
2 ^ 3computes “2 to the power of 3,” which results in 8. Just like addition or multiplication, exponentiation is written in an infix style with the operator between its two arguments. This gives you a concise way to express repeated multiplication in your Haskell code.
-
IntA fixed-size integer type used for whole numbers. It does not support fractional values and cannot be used with the/operator. -
DoubleA floating-point type used for real numbers with fractional parts. It belongs to a fractional family of types and works with the/operator. -
Arithmetic operators (
+,-,*) Built-in operators for addition, subtraction, and multiplication. They work naturally withIntas well as other numeric types. -
Division operator (
/) The standard division operator in Haskell, which requires a fractional type such asDouble. It is not defined for plainInt. -
Fractional(as in “No instance for Fractional Int”) A class of types that support fractional division.Doubleis an example;Intis not. You will learn more about this when you study type classes. -
divfunction A function for integer division that takes two integers, performs division, and rounds down to the nearestInt. -
Negation (prefix
-) A unary operator used before a number to make it negative, such as-5. Parentheses can be used to avoid ambiguity in complex expressions. -
Exponentiation (
(^)) An infix operator used to raise a number to an integer power, as in2 ^ 3, which evaluates to 8. -
Strongly typed A property of Haskell meaning that it enforces types strictly and does not perform hidden or implicit conversions between types.
Bernard Sibanda is a global Technology Entrepreneur, Web3 and Software Consultant with a deep focus on Cardano Blockchain, Midnight and Community building.
Key Positions:
- Founder, CTO, Developer Advocate cohort #1, Fullstake Developer, Cardano Ambassador, Catalyst Project Manager, DREP-WIMS:
- Co-founder of ABL Tech and Cardano Africa Live
- EBU-certified Plutus Pioneer (Plutus/Haskell)
- Cohort #1 Plutus Pioneer Developer
- Catalyst Community Reviewer & Funded Projects Manager
-
DRep for WIMS-Cardano (ID:
drep1yguj8zu48n99pv70yl6ckzt9hdgjy8yjnlqs2uyzcpafnjgu4vkul) - Intersect Developer Advocate
- Intersect Committe Member 2025-2026
- Cardano Marketer,Promoter and blogger
- Cardano Open Source Contributor
- Cardano communities and events organizer and builder
- Cardano Ambassador for South Africa
Official links:
- Stablecoins Dex
- Coxygen Global Universities
- WIMS Cardano Global
- Cardano Africa Live
- WIMS Cardano Videos
- Cardano Smart Contract Videos
- Fullstack IT Consulting
Social links: