7po3j-syaaa-aaaal-qbqea-cai.icp0.io
Open in
urlscan Pro
2a0b:21c0:b002:2:5000:edff:fe0d:98de
Public Scan
URL:
https://7po3j-syaaa-aaaal-qbqea-cai.icp0.io/advanced-types/type-bounds.html
Submission: On December 19 via api from US — Scanned from GB
Submission: On December 19 via api from US — Scanned from GB
Form analysis
1 forms found in the DOM<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
Text Content
1. The Motoko Programming Language 2. 3. Part 1 4. 1. Introduction ❱ 5. 1. 1.1. Getting Started 6. 2. Common Programming Concepts ❱ 7. 1. 2.1. Variables 2. 2.2. Mutability 3. 2.3. Comments 4. 2.4. Types ❱ 5. 1. 2.4.1. Tuples 2. 2.4.2. Records 3. 2.4.3. Variants 4. 2.4.4. Immutable Arrays 5. 2.4.5. Mutable Arrays 6. 2.5. Operators ❱ 7. 1. 2.5.1. Numeric operators 2. 2.5.2. Relational operators 3. 2.5.3. Assignment operators 4. 2.5.4. Text concatenation 5. 2.5.5. Logical expressions 6. 2.5.6. Bitwise operators 7. 2.5.7. Operator precedence 8. 2.6. Pattern Matching 9. 2.7. Functions 10. 2.8. Options and Results 11. 2.9. Control Flow ❱ 12. 1. 2.9.1. If Expression 2. 2.9.2. If Else Expression 3. 2.9.3. Switch Expression 13. 2.10. Objects and Classes ❱ 14. 1. 2.10.1. Objects 2. 2.10.2. Classes 15. 2.11. Modules and Imports 16. 2.12. Assertions 8. 3. Internet Computer Programming Concepts ❱ 9. 1. 3.1. Actors ❱ 2. 1. 3.1.1. From Actor to Canister 2. 3.1.2. Canister Calls from Clients 3. 3.2. Principals and Authentication 4. 3.3. Async Data ❱ 5. 1. 3.3.1. Shared Types 2. 3.3.2. Candid 6. 3.4. Basic Memory Persistence ❱ 7. 1. 3.4.1. Upgrades 2. 3.4.2. Stable Variables 10. 11. Part 2 12. 4. Advanced Types ❱ 13. 1. 4.1. Generic Types 2. 4.2. Subtyping 3. 4.3. Recursive Types 4. 4.4. Type Bounds 14. 5. The Base Library ❱ 15. 1. 5.1. Primitive Types ❱ 2. 1. 5.1.1. Bool 2. 5.1.2. Nat 3. 5.1.3. Int 4. 5.1.4. Float 5. 5.1.5. Principal 6. 5.1.6. Text 7. 5.1.7. Char 8. 5.1.8. Bounded Number Types ❱ 9. 1. 5.1.8.1. Nat8 2. 5.1.8.2. Nat16 3. 5.1.8.3. Nat32 4. 5.1.8.4. Nat64 5. 5.1.8.5. Int8 6. 5.1.8.6. Int16 7. 5.1.8.7. Int32 8. 5.1.8.8. Int64 10. 5.1.9. Blob 3. 5.2. Utility Modules ❱ 4. 1. 5.2.1. Iterators 2. 5.2.2. Hash 3. 5.2.3. Option 4. 5.2.4. Result 5. 5.2.5. Order 6. 5.2.6. Error 7. 5.2.7. Debug 5. 5.3. Data Structures ❱ 6. 1. 5.3.1. Array 2. 5.3.2. List 3. 5.3.3. Buffer 4. 5.3.4. HashMap 5. 5.3.5. RBTree 7. 5.4. More Data Structures 8. 5.5. IC APIs ❱ 9. 1. 5.5.1. Time 2. 5.5.2. Timer 3. 5.5.3. CertifiedData 4. 5.5.4. Random 5. 5.5.5. Experimental 16. 6. Advanced Concepts ❱ 17. 1. 6.1. Async Programming 2. 6.2. Scalability ❱ 3. 1. 6.2.1. Actor Classes 2. 6.2.2. Stable Storage 4. 6.3. System API's ❱ 5. 1. 6.3.1. Message Inspection 2. 6.3.2. Timers 3. 6.3.3. Certified Variables 4. 6.3.4. Pre-upgrade and Post-upgrade 5. 6.3.5. Cryptographic Randomness 18. 19. Part 3 20. 7. Project Deployment ❱ 21. 1. 7.1. Installing the SDK 2. 7.2. Local Deployment 3. 7.3. Canister Status 4. 7.4. Identities and PEM Files 5. 7.5. Cycles and ICP 6. 7.6. Cycles Wallet 7. 7.7. IC Deployment 22. 8. Common Internet Computer Canisters ❱ 23. 1. 8.1. IC Management Canister 2. 8.2. ICP Ledger Canister 3. 8.3. Cycle Minting Canister 24. 9. Internet Computer Standards ❱ 25. 1. 9.1. ICRC1 26. 10. Tokenized Comments Example 27. 28. APPENDIX 29. 11. TABLES * Light * Rust * Coal * Navy * Ayu THE MOTOKO PROGRAMMING LANGUAGE BOOK TYPE BOUNDS When we express a subtype-supertype relationship by writing T <: U, then we say that T is a subtype by U. We can use this relationship between two types in the instantiation of generic types in functions. TYPE BOUNDS IN FUNCTIONS Consider the following function signature: func makeNat<T <: Number>(x : T) : Natural It's a generic function that specifies a type bound Number for its generic type parameter T. This is expressed as <T <: Number>. The function takes an argument of generic bounded type T and returns a value of type Natural. The function is meant to take a general kind of number and process it into a Nat. The types Number and Natural are declared like this: type Natural = { #N : Nat; }; type Integer = { #I : Int; }; type Floating = { #F : Float; }; type Number = Natural or Integer or Floating; The types Natural, Integer and Floating are just variants with one field and associated types Nat, Int and Float respectively. The Number type is a type union of Natural, Integer and Floating. A type union is constructed using the or keyword. This means that a Number could be either a Natural, an Integer or a Floating. We would use these types to implement our function like this: import Int "mo:base/Int"; import Float "mo:base/Float"; func makeNat<T <: Number>(x : T) : Natural { switch (x) { case (#N n) { #N n; }; case (#I i) { #N(Int.abs(i)); }; case (#F f) { let rounded = Float.nearest(f); let integer = Float.toInt(rounded); let natural = Int.abs(integer); #N natural; }; }; }; After importing the Int and Float modules from the Base Library, we declare our function and implement a switch expression for the argument x. In case we find a #N we know we are dealing with a Natural and thus immediately return the the same variant and associated value that we refer to as n. In case we find an #I we know we are dealing with an Integer and thus take the associated value i and apply the abs() function from the Int module to turn the Int into a Nat. We return a value of type Natural once again. In case we find a #F we know we are dealing with a Floating. So we take the associated value f of type Float, round it off and convert it to an Int using functions from the Float module and convert to a Nat again to return a value of type Natural once again. Lets test our function using some assertions: assert makeNat(#N 0) == #N 0; assert makeNat(#I(-10)) == #N 10; assert makeNat(#F(-5.9)) == #N 6; We use arguments of type Natural, Integer and Floating with associated types Nat, Int and Float respectively. They all are accepted by our function. In all three cases, we get back a value of type Natural with an associated value of type Nat. THE ANY AND NONE TYPES All types in Motoko are bounded by a special type, namely the Any type. This type is the supertype of all types and thus all types are a subtype of the Any type. We may refer to it as the top type. Any value or expression in Motoko can be of type Any. Another special type in Motoko is the None type. This type is the subtype of all types and thus all types are a supertype of None. We may refer to it as the bottom type. No value in Motoko can have the None type, but some expressions can. > NOTE > Even though no value has type None, it is still useful for typing expressions > that don't produce a value, such as infinite loops, early exits via return and > throw and other constructs that divert control-flow (like Debug.trap : Text -> > None) For any type T in Motoko, the following subtype-supertype relationship holds: None <: T T <: Any