MojoでProject Euler 54

https://projecteuler.net/problem=54

各役をC++のように基底クラスを継承したいのですが、どうやったらいいのでしょうね。同じくTraitを使うRustは頑張れば同じVecに入れられるのですが、MojoだとListに入れられるのでしょうか。

import sys


#################### List ####################

trait Printable(CollectionElement, Stringable):
    pass

fn print_list[T: Printable](a: List[T]):
    if a.size > 0:
        var s = "[" + str(a[0])
        for i in range(1, a.size):
            s += ", " + str(a[i])
        s += "]"
        print(s)
    else:
        print("[]")

fn reverse_list[T: CollectionElement](a: List[T]) -> List[T]:
    var b = List[T]()
    for i in range(len(a) - 1, -1, -1):
        b.append(a[i])
    return b


#################### Card ####################

@value
struct Card:
    var suit: String
    var number: Int
    
    @staticmethod
    fn create(s: String) raises -> Card:
        var suit = s[1]
        if s[0] == 'T':
            return Card(suit, 10)
        elif s[0] == 'J':
            return Card(suit, 11)
        elif s[0] == 'Q':
            return Card(suit, 12)
        elif s[0] == 'K':
            return Card(suit, 13)
        elif s[0] == 'A':
            return Card(suit, 14)
        else:
            var num = atol(s[0])
            return Card(suit, num)


#################### Rank ####################

@value
struct Rank:
    var freq: List[Int]
    var rank: Int
    
    fn __init__(inout self, freq: List[Int], name: String):
        self.freq = freq
        if name == "HighCard":
            self.rank = 1
        elif name == "OnePair":
            self.rank = 2
        elif name == "TwoPairs":
            self.rank = 3
        elif name == "ThreeCard":
            self.rank = 4
        elif name == "Straight":
            self.rank = 5
        elif name == "Flush":
            self.rank = 6
        elif name == "FullHouse":
            self.rank = 7
        elif name == "FourCards":
            self.rank = 8
        elif name == "StraightFlush":
            self.rank = 9
        else:
            self.rank = 10
    
    fn sum_cards(self) -> Int:
        var s = 0
        for elem in self.freq:
            var num = elem[] & 15
            var f = elem[] >> 4
            s += num * f
        return s
    
    fn __gt__(self, other: Rank) -> Bool:
        if self.rank != other.rank:
            return self.rank > other.rank
        
        for i in range(len(self.freq)):
            if self.freq[i] != other.freq[i]:
                return self.freq[i] > other.freq[i]
        else:
            return False
    
    @staticmethod
    fn create(hand: Hand) -> Rank:
        var freq = hand.frequency()
        if hand.is_straight():
            if hand.is_flush():
                if hand.sum() == 60:
                    return Rank(freq, "RolyalFlush")
                else:
                    return Rank(freq, "StraightFlush")
            else:
                return Rank(freq, "Straight")
        elif hand.is_flush():
            return Rank(freq, "Flush")
        elif len(freq) == 5:
            return Rank(freq, "HighCard")
        elif len(freq) == 4:
            return Rank(freq, "OnePair")
        elif len(freq) == 3:
            if (freq[0] & 15) == 2:
                return Rank(freq, "TwoPairs")
            else:
                return Rank(freq, "ThreeCard")
        else:
            if (freq[0] & 15) == 3:
                return Rank(freq, "FullHouse")
            else:
                return Rank(freq, "FourCards")


#################### Hand ####################

@value
struct Hand:
    var cards: List[Card]
    
    fn frequency(self) -> List[Int]:
        var s = 0
        for card in self.cards:
            s += 1 << (3 * card[].number)
        
        # [num + (freq << 4)]
        var freq = List[Int]()
        for num in range(2, 15):
            var f = (s >> (num * 3)) & 7
            if f != 0:
                freq.append(num + (f << 4))
        sort(freq)
        return reverse_list(freq)
    
    fn is_flush(self) -> Bool:
        for card in self.cards:
            if card[].suit != self.cards[0].suit:
                return False
        else:
            return True
    
    fn is_straight(self) -> Bool:
        var s = 0
        for card in self.cards:
            s |= 1 << card[].number
        while (s & 1) == 0:
            s >>= 1
        return s == 31
    
    fn sum(self) -> Int:
        var s = 0
        for card in self.cards:
            s += card[].number
        return s
    
    fn compare_straight(self, other: Hand) -> Bool:
        var bf1 = self.is_flush()
        var bf2 = other.is_flush()
        if bf1 == bf2:
            return self.sum() > other.sum()
        else:
            return bf1
    
    fn __gt__(self, other: Hand) -> Bool:
        var rank1 = Rank.create(self)
        var rank2 = Rank.create(other)
        return rank1 > rank2
    
    @staticmethod
    fn read(path: String) -> List[Hand]:
        try:
            var hands = List[Hand]()
            with open(path, "r") as f:
                var data = f.read()
                var lines = data.split("\n")
                for line in lines:
                    if line[] == "":
                        break
                    var v = line[].split(" ")
                    hands.append(Hand.create(v[:5]))
                    hands.append(Hand.create(v[5:]))
            return hands
        except:
            return List[Hand]()
    
    @staticmethod
    fn create(v: List[String]) raises -> Hand:
        var cards = List[Card]()
        for s in v:
            cards.append(Card.create(s[]))
        return Hand(cards)


#################### process ####################

fn f(path: String) -> Int:
    var hands = Hand.read(path)
    var counter = 0
    for i in range(0, len(hands), 2):
        if hands[i] > hands[i+1]:
            counter += 1
    return counter

fn main() raises:
    var args = sys.argv()
    var path = args[1]
    print(f(path))