microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/fix-wasm-logging-issue

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

samples/language/ClassConstraints.qs

56lines · modecode

1// # Sample
2// Class Constraints
3//
4// # Description
5// Q# supports constraining generic types via _class constraints_. The formal term for this concept is bounded polymorphism,
6// or parametric polymorphism.
7
8// A generic type, or type parameter, is specified on a callable declaration to signify that a function can take multiple types of data as input.
9// For a generic type parameter to be useful, we need to be able to know enough about it to operate on it. This is where class constraints come in. By specifying
10// class constraints for a type parameter, we are limiting what types can be passed as arguments to a subset with known properties.
11
12// Classes that Q# currently supports are:
13// - `Eq`: denotes that a type can be compared to other values of the same type via the `==` operator.
14// - `Add`: denotes that a type can be added to other values of the same type via the `+` operator.
15// - `Mul`: denotes that a type can be used with the multiplication (`*`) operator.
16// - `Mod`: denotes that a type can be used with the modulo (`%`) operator.
17// - `Sub`: denotes that a type can subtracted from other values of the same type via the `-` operator.
18// - `Div`: denotes that a type can subtracted from other values of the same type via the `/` operator.
19// - `Signed`: denotes that a type can be negated or made positive with `+` or `-` unary operator prefixes.
20// - `Ord`: denotes that a type can be used with comparison operators (`>`, `<`, `>=`, `<=`).
21// - `Show`: denotes that a type can be converted to a string via format strings (`$"number: {num}"`).
22// - `Exp['T]`: denotes that a type can be raised to a power of type `'T`. The return type of exponentiation is the type of the base.
23// - `Integral`: denotes that a type is an integer-ish type, i.e., can be used in following expressions using the following operators: `&&&`, `|||`, `^^^`, `<<<`, and `>>>`.
24
25// For example, we may want to write a function that checks if a list is full of entirely the same item. `f([3, 3, 3])` would be `true` and `f([3, 4])` would be false.
26function AllEqual<'T : Eq>(items : 'T[]) : Bool {
27 let allEqual = true;
28 for i in 1..Length(items) - 1 {
29 if items[i] != items[i - 1] {
30 return false;
31 }
32 }
33 return true;
34}
35
36function Main() : Unit {
37 let is_equal = AllEqual([1, 1, 1]);
38 Message($"{is_equal}");
39
40 let is_equal = AllEqual([1, 2, 3]);
41 Message($"{is_equal}");
42
43 // Because we wrote this function generically, we are able to pass in different types, as
44 // long as they can be compared via the class `Eq`.
45 let is_equal = AllEqual([true, true, false]);
46 Message($"{is_equal}");
47
48 let is_equal = AllEqual(["a", "b"]);
49 Message($"{is_equal}");
50
51 let is_equal = AllEqual([[], [1]]);
52 Message($"{is_equal}");
53
54 let is_equal = AllEqual([[1], [1]]);
55 Message($"{is_equal}");
56}
57