Type conversions
Conversions are used to transform values between different types to ensure compatibility and ease of manipulation. Common conversions include numeric transformation, such as converting Float or Int to Nat, and text manipulation, like converting Text to Float or encoding Text as a Blob. Arrays and tuples can be converted into structured types, such as records or hashmaps, for better organization. Additionally, time conversions enable transforming Time.now() (nanoseconds since 1970) into human-readable date formats, with optional timezone adjustments. These conversions provide flexibility when working with different data types.
Converting types to Nat
Section titled “Converting types to Nat”Motoko provides methods for converting both Float and Int to Nat. Since Nat only represents non-negative integers, the conversion must handle cases where the original value is negative or contains a decimal.
Float to Nat
Section titled “Float to Nat”A Float can be converted to Nat using Float.toInt, followed by Int.abs to ensure a non-negative value.
import Float "mo:core/Float";import Int "mo:core/Int";
func floatToNat(f : Float) : Nat { Int.abs(Float.toInt(f));};
let result1 = floatToNat(42.9); // 42let result2 = floatToNat(-15.6); // 15 (absolute value is taken)Int to Nat
Section titled “Int to Nat”Int can be directly converted to Nat using Int.abs, which removes any negative sign.
import Int "mo:core/Int";
func intToNat(i : Int) : Nat { Int.abs(i);};
// Example usagelet result3 = intToNat(10); // 10let result4 = intToNat(-5); // 5Modifying types
Section titled “Modifying types”Nat8 to Char
Section titled “Nat8 to Char”Motoko allows converting a Nat8 value to a Char, where the Nat8 value represents a Unicode scalar value in the ASCII range.
Since Nat8 is a bounded type (0–255), it must be explicitly widened to Nat32 before being converted into Char.
import Char "mo:core/Char";import Nat8 "mo:core/Nat8";import Nat32 "mo:core/Nat32";
persistent actor CharConverter{ func nat8ToChar(n : Nat8) : Char { Char.fromNat32(Nat32.fromNat(Nat8.toNat(n))); }; nat8ToChar(65); // 'A'};Text to lowercase
Section titled “Text to lowercase”Motoko provides a built-in function Text.toLower, which converts all characters in a string to lowercase.
import Text "mo:core/Text";
persistent actor CaseConverter{ func toLowercaseExample(s : Text) : Text { return Text.toLower(s); };
toLowercaseExample("HELLO WORLD"); // "hello world"};Text to an optional Blob for a ledger memo
Section titled “Text to an optional Blob for a ledger memo”Text can be converted into a Blob using Text.encodeUtf8. To make it optional (?Blob), it can be wrapped in ?.
import Text "mo:core/Text";
persistent actor TextToBlobConverter { func textToOptionalBlob(s : Text) : ?Blob { ?Text.encodeUtf8(s); }; textToOptionalBlob("Payment Memo"); // ?Blob};Text to Float
Section titled “Text to Float”Non-shared type to shared type
Section titled “Non-shared type to shared type”| Non-shared type | Shared equivalent | Conversion method |
|---|---|---|
Mutable array [var T] | Array [T] | Array.freeze(mutArr) |
Time.now() to date
Section titled “Time.now() to date”On ICP, time is measured in nanoseconds since the Unix epoch (January 1, 1970, UTC). The Time.now() function returns the current system time in nanoseconds, which must be converted accordingly for date and time.
Modifying arrays
Section titled “Modifying arrays”Array to Text
Section titled “Array to Text”Text.fromArray converts a Char into a Text. When working with different types, elements must be converted to Text before transformation.
import Text "mo:core/Text";
assert Text.fromArray(['a', 'b', 'c']) == "abc";For arrays containing numbers or other types, each element is converted to Text before joining them into a single string.
import Text "mo:core/Text";import Array "mo:core/Array";import Nat "mo:core/Nat";
func arrayOfNatToText(arr : [Nat]) : Text { Text.join(" ", Array.map<Nat, Text>(arr, Nat.toText).values())};
assert arrayOfNatToText([1, 2, 3]) == "1 2 3";Array of tuples to an object
Section titled “Array of tuples to an object”Motoko lacks support for dynamic objects, so an array of tuples is converted into a record or a structured representation.
import HashMap "mo:core/HashMap";import Text "mo:core/Text";
persistent actor MapConverter { func arrayToMap(arr : [(Text, Nat)]) : HashMap.HashMap<Text, Nat> { let map = HashMap.HashMap<Text, Nat>(arr.size(), Text.equal, Text.hash); for ((key, value) in arr.vals()) { map.put(key, value) }; map }};
arrayToMap([("Motoko", 4), ("Ghost", 21)]);To convert an array of tuples [(Text, Nat)] into a custom record type, such as User, Array.map is used to transform each tuple into a structured record.
import Array "mo:core/Array";type User = { name : Text; age : Nat;};persistent actor TupleConverter{ func tuplesToUsers(arr : [(Text, Nat)]) : [User] { Array.map<(Text, Nat), User>(arr, func((name, age)) { { name; age } }); }};
tuplesToUsers([("Motoko", 4), ("Ghost", 21)]);