Operators
Keel provides a rich set of operators for arithmetic, comparison, logical operations, and more.
Arithmetic Operators
Basic mathematical operations:
| Operator | Description | Example |
|---|---|---|
+ | Addition | 1 + 2 |
- | Subtraction | 5 - 3 |
* | Multiplication | 4 * 2 |
/ | Division | 10 / 3 |
// | Integer division | 10 // 3 |
% | Modulo | 10 % 3 |
^ | Power | 2 ^ 8 |
let addition = 5 + 3
let subtraction = 10 - 4
let multiply = 6 * 7
let divide = 15 / 3
let intDiv = 10 // 3
let modulo = 17 % 5
let power = 2 ^ 10
let negative = -42 -- -42 (negation)
power
Try itInteger vs Float Division
Division behavior:
let floatDiv = 10 / 3
let intDiv = 10 // 3
(floatDiv, intDiv)
Try itNumeric Type Promotion
When mixing Int and Float, Int is promoted to Float:
let x = 1 + 2.5
let y = 3 * 1.5
x + y
Try itComparison Operators
Compare values and return Bool:
| Operator | Description | Example |
|---|---|---|
== | Equal | a == b |
!= | Not equal | a != b |
< | Less than | a < b |
<= | Less than or equal | a <= b |
> | Greater than | a > b |
>= | Greater than or equal | a >= b |
let eq = 5 == 5
let neq = 5 != 6
let lt = 3 < 5
let gt = 5 > 3
let lte = 3 <= 3
let gte = 5 >= 4
(eq, neq, lt, gt, lte, gte)
Try itLogical Operators
Boolean logic operations:
| Operator | Description | Example |
|---|---|---|
&& | Logical AND | a && b |
|| | Logical OR | a || b |
not | Logical NOT | not a |
-- And (both must be True)
let and1 = True && True
let and2 = True && False
-- Or (at least one must be True)
let or1 = True || False
let or2 = False || False
-- Not (negation)
let not1 = not True -- False
let not2 = not False -- True
let not3 = not (1 > 2)
-- True
let not4 = not not True -- True (double negation)
(and1, or1, not1, not3)
Try itShort-circuit Evaluation
Logical operators use short-circuit evaluation:
-- False && ... returns False immediately without evaluating the right side
let result = False && True
result -- False
Try itString Operators
String manipulation:
"Hello, " ++ "World!"
Try itList Operators
Working with lists:
| Operator | Description | Example |
|---|---|---|
:: | Cons (prepend) | 1 :: [2, 3] |
++ | Concatenation | [1, 2] ++ [3, 4] |
-- Cons (prepend element)
let consed1 =
1 :: [2, 3]
let consed2 : List Int = 1 :: (2 :: [])
-- Concatenation
let joined =
[1, 2] ++ [3, 4]
joined
Try itPipe Operators
Chain function calls elegantly:
| Operator | Description | Example |
|---|---|---|
|> | Pipe forward | x |> f |
<| | Pipe backward | f <| x |
fn double: Int -> Int
fn double x =
x * 2
fn addOne: Int -> Int
fn addOne x =
x + 1
-- Forward pipe
5
|> double -- Same as: double 5 = 10
Try itimport List
-- Pipeline example
[1, 2, 3, 4, 5]
|> List.filter (|x| x > 2)
|> List.map (|x| x * 2)
-- [6, 8, 10]
Try itFunction Composition
Compose functions into new functions:
| Operator | Description | Example |
|---|---|---|
>> | Compose (left to right) | f >> g |
<< | Compose (right to left) | g << f |
-- Forward composition (f first, then g)
let addOne = |x: Int| x + 1
let double = |x: Int| x * 2
let addThenDouble = addOne >> double
addThenDouble 5 -- 12 (5 + 1 = 6, 6 * 2 = 12)
Try it-- Backward composition (g first, then f)
let addOne = |x: Int| x + 1
let double = |x: Int| x * 2
let doubleThenAdd = addOne << double
doubleThenAdd 5 -- 11 (5 * 2 = 10, 10 + 1 = 11)
Try itBest Practices
- Use parentheses when precedence is unclear
- Prefer pipes (
|>) for data transformation chains - Use composition (
>>) to build reusable function pipelines - Use
!=for inequality (not/=)
Next Steps
Learn about functions to create reusable code.