How to declare a variable variant type and compare variants?

I declared the following types:

type cell = { #dead; #alive};
type universe = {
                 width : Nat;
                 height : Nat;
                 cells : [var cell] 
                 };

var universe1 : universe ={
    width = 4;
    height = 4;
    cells = [var 
            #dead, #alive, #alive, #dead,
            #dead, #alive, #alive, #alive,
            #dead, #dead, #dead, #dead,
            #alive, #alive, #alive ,#dead
            ];

var universe2 : universe ={
    width = 4;
    height = 4;
    cells = [var 
            #dead, #alive, #alive, #dead,
            #dead, #alive, #alive, #alive,
            #dead, #dead, #dead, #dead,
            #alive, #alive, #alive ,#dead
            ];
};

I now want to compare universe1.cells and universe2.cells with Array.equals

import Array ā€mo:stdlib/arrayā€

if(Array.equals<cell>(universe1.cells : [var cell], universe2.cells : [var cell], eq)) Debug.print(ā€žhiā€œ);

My problem - as you probably noticed - is, that the universe.cells produces [var cell] and i donā€˜t understand how to either declare <var cell> (doesnt work) or type cell = var {#dead; #alive}; (doesnt work either).

The second problem is that i donā€˜t understand how to compare two variant types (#dead and #alive) to check if theyā€˜re equal (this is needed for the eq function in Array.equals from above). The old fashioned #dead == #alive doesnt work.

Help would be highly appreciated!
@alexa.smith @hansl @enzo

3 Likes

@Nick might have some thoughts on this too.

2 Likes

This should work:

import Debug "mo:stdlib/debug";

actor {

    type Cell = { #dead; #alive };

    func cellEq(a : Cell, b : Cell) : Bool {
        switch (a, b) {
            case (#dead, #dead) true;
            case (#alive, #alive) true;
            case (#dead, #alive) false;
            case (#alive, #dead) false;
        }
    };

    type universe = {
        width : Nat;
        height : Nat;
        cells : [var Cell]
    };

    var universe1 : universe = {
        width = 4;
        height = 4;
        cells = [var
            #dead, #alive, #alive, #dead,
            #dead, #alive, #alive, #alive,
            #dead, #dead, #dead, #dead,
            #alive, #alive, #alive ,#dead
        ];
    };

    var universe2 : universe = {
        width = 4;
        height = 4;
        cells = [var
            #dead, #alive, #alive, #dead,
            #dead, #alive, #alive, #alive,
            #dead, #dead, #dead, #dead,
            #alive, #alive, #alive ,#dead
        ];
    };

    // TODO: Add this to the standard library!
    func Array_equalsVar<A>(
        a : [var A],
        b : [var A],
        eq : (A, A) -> Bool
    ) : Bool {
        if (a.len() != b.len()) {
            return false
        };
        var i = 0;
        while (i < a.len()) {
            if (not eq(a[i], b[i])) {
                return false
            };
            i += 1
        };
        true
    };

    public func main() {
        if (Array_equalsVar<Cell>(universe1.cells, universe2.cells, cellEq)) {
            Debug.print("hi")
        }
    };

}
3 Likes

I know itā€™s a little annoying that the compiler does not derive equality functions for you, but Joachim and the team are aware. The feature has already been requested. With respect to variable declarations in type annotations, I could submit a PR to enter equalsVar into the standard library, but perhaps I should first touch base with Claudio, who wrote the Motoko parser. It seems that parentheses are not recognized as valid separators within type annotations, which is strange because square brackets are. I would have expected Array.equals<(var Cell)> to work. I should let Claudio clarify the details on that.

6 Likes

thats a very elegant solution! thank you very much, i appreciate the effort :seedling:

so far i have to say iā€˜m pretty impressed by motoko. iā€˜m not very familiar with statically typed or functional languages, but it becomes familiar quite fast. especially looking at code examples from more experienced programmers is a great help, iā€˜m really looking forward to the time when i can just google stuff like that or consult stackoverflow.

in case anyone is interested in what im trying to do (some of you might have already guessed it):

3 Likes

Slightly tangental but if you are building a version of Conwayā€™s ā€œGame of Lifeā€ for the IPC you might enjoy this Dr Dobbs article from the excellent but now sadly retired magazine. https://www.drdobbs.com/jvm/an-algorithm-for-compressing-space-and-t/184406478

5 Likes

Sad news from last weekend:

2 Likes