Open4

mojo練習

おもちメタルおもちメタル

左辺値推論がないのはどうなんだろう?
とりあえず初手でコケた。

# ok
let s = S[1]()

# ng 1, 左辺値推論がない
let s: S[1] = S()

# ng 2, 右辺値だけども・・・
let s: S = S[1]()
おもちメタルおもちメタル

これはなんだろう?

error: Expression [30]:30:10: use of uninitialized value 'anonymous*'
    s.add(S[2]()).p()
         ^
おもちメタルおもちメタル

型パラメータ部分で関数呼び出しができる!

struct S[value: Int]:
    fn __init__(self&):
        pass
    
    fn p(self):
        print(value)
    
    fn compose[o: Int](self, other: S[o]) -> S[compute(value, o)]:
        return S[compute(value, o)]()

fn compute(a: Int, b: Int) -> Int:
    return a * 2 + b
    
let s = S[2]()
let t = s.compose(S[1]())
t.p() # 5
おもちメタルおもちメタル

なんか非自明な制限があるね

struct S[value: Int]:
    fn __init__(self&):
        pass
    
    fn v(self) -> Int:
        return value
    
    fn p(self):
        print(value)
    
    fn compose[o: Int](self, other: S[o]) -> S[compute(value, o)]:
        return S[compute(value, o)]()

    fn double(self) -> S[value * 2]:
        return S[value * 2]()
    
    fn hyperDouble(self) -> S[metaV(helper(S[value]()))]:
        return S[metaV(helper(S[value]()))]()

fn helper[v: Int](s: S[v]) -> S[v * 2]:
    return S[v * 2]()

fn metaV[v: Int](s: S[v]) -> Int:
    return s.v()

fn compute(a: Int, b: Int) -> Int:
    return a * 2 + b
    
let s = S[1]()
print(s.v())
error: Expression [2]:21:52: cannot synthesize lvalue of non-register-passable type S[value] in type parameter
    fn hyperDouble(self) -> S[metaV(helper(S[value]()))]:
                                                   ^

error: Expression [2]:22:39: cannot synthesize lvalue of non-register-passable type S[value] in type parameter
        return S[metaV(helper(S[value]()))]()
                                      ^