microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/bounds

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/language/ClassConstraints.qs

44lines · 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// The currently supported classes are `Exp`, for exponentiation; `Eq`, for comparison via the `==` operator; `Add`, for addition via the `+` operator;
8// `Num`, if a type is numeric; `Integral`, if a type is a form of integer; and `Show`, if a type can be rendered as a string.
9
10// 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.
11// 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
12// class constraints for a type parameter, we are limiting what types can be passed as arguments to a subset with known properties.
13
14// Classes that Q# currently supports are:
15// - `Eq`: denotes that a type can be compared to other values of the same type via the `==` operator.
16// - `Add`: denotes that a type can be added to other values of the same type via the `+` operator, and the return type of this addition is also of the same type.
17// - `Show`: denotes that a type can be converted to a string via format strings (`$"number: {num}"`).
18// - `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.
19// - `Num`: denotes that a type can be used in `>`, `>=`, `<`, `<=`, `/`, `%`, `*`, and `-` operator expressions.
20// - `Integral`: denotes that a type is an integer-ish type, i.e., can be used in following expressions using the following operators: `&&&`, `|||`, `^^^`, `<<<`, and `>>>`.
21
22// 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.
23function AllEqual<'T : Eq > (items : 'T[]) : Bool {
24 let allEqual = true;
25 for i in 1..Length(items) - 1 {
26 if items[i] != items[i - 1] {
27 return false;
28 }
29 }
30 return true;
31}
32
33function Main() : Unit {
34 Message($"{AllEqual([1, 1, 1])}");
35 Message($"{AllEqual([1, 2, 3])}");
36
37 // Because we wrote this function generically, we are able to pass in different types, as
38 // long as they can be compared via the class `Eq`.
39 Message($"{AllEqual([true, true, false])}");
40 Message($"{AllEqual(["a", "b"])}");
41
42 Message($"{AllEqual([[], [1]])}");
43 Message($"{AllEqual([[1], [1]])}");
44}