Skip to content
Playground

制御構文

制御構文は、特に断らない限り式として使える。

if

yulang
if x > 0: "positive" else: "non-positive"

if cond:
    a
else:
    b

if cond { a } else { b }

if の条件は bool である。 else がない場合は statement-like になり、then 分岐は効果のために評価され、値は捨てられ、式全体は () を返す。

elsif

elsififelse の間に条件を追加する。 条件は左から順に試され、最初に真になった分岐が選ばれる。 すべて偽なら else が選ばれる。

yulang
my size n =
    if n < 0: "negative"
    elsif n == 0: "zero"
    elsif n < 10: "small"
    else: "large"

say (size 7)

case

yulang
case value:
    0 -> "zero"
    n if n < 0 -> "negative"
    _ -> "other"

case arm は上から順に試される。 guard は pattern の後ろに if を書く。

guard

case の guard は pattern の後ろに if または where で書く。 guard からは pattern が bind した名前を参照できる。 pattern がマッチした後だけ guard が評価され、偽なら次の arm へ進む。

yulang
my sign n = case n:
    value if value < 0 -> "negative"
    value if value == 0 -> "zero"
    _ -> "positive"

say (sign 3)

catch

yulang
act console:
    our read: () -> str

catch console::read():
    console::read(), k -> k "42"
    value -> value

operation arm は operation の payload と continuation k を受け取る。 k value を呼ぶと計算を再開する。 value arm は通常終了を処理する。

guard

catch の guard は operation pattern と continuation の後ろに if または where で書く。 guard が偽ならその arm は選ばれず、次にマッチする arm が試される。

yulang
act signal:
    our ask: () -> int

my result = catch signal::ask():
    signal::ask(), k if false -> 0
    signal::ask(), k -> k 42
    value -> value

say result

casecatch のラベル

case 'label value:catch 'label action: は arm 集合全体に再帰名を付ける。 label は個々の arm ではなく、arm 集合に属する。 body から 'label next を呼ぶと、同じ case または catch の arm が next に再適用される。

yulang
my result = case 'count 3:
    0 -> "done"
    n -> 'count (n - 1)

say result

同じ綴りで labelled catch に再入できる。

yulang
my result = catch 'again 3:
    n if n > 0 -> 'again (n - 1)
    n -> n

say result

for

yulang
for x in 0..10:        // 11 回反復: 0..10 は閉区間 (半開は 0..<10)
    say x

for x in xs:Fold を実装する値を走査する。 body は関数へ lower され、plain な for expression は () を返す。

ループ制御は prelude から入る。

yulang
for x in 0..:
    if x == 10: last

lastnextredo は、現在のループから抜ける、次の反復へ進む、反復をやり直すための操作である。

ラベル

yulang
for 'outer x in 0..:
    for y in 0..:
        if y == 3: last 'outer

labelled ループは label 値を body に渡す。 last 'outernext 'outerredo 'outer は、その label のループを対象にする。

subreturn

yulang
sub:
    for x in 0..:
        if x == 5: return x
    0

sub: は早期 return scope を作る。 return value は直近の sub: から抜ける。 nullfix の return() を返す。

labelled sub もある。

yulang
sub 'done:
    'done.return 42
    0

subreturnlastnextredo は標準ライブラリ / prelude の surface である。 parser 専用 keyword ではない。

Block と Lambda

yulang
{
    my x = 1
    x + 1
}

my inc = \x -> x + 1
my add = \x y -> x + y

(inc 1, add 1 2)

block は statement を順に評価し、最後の式を返す。 ラムダは \ で始まり、複数引数は curried 関数として扱われる。

Yulang