制御構文
制御構文は、特に断らない限り式として使える。
if
if x > 0: "positive" else: "non-positive"
if cond:
a
else:
b
if cond { a } else { b }if の条件は bool である。 else がない場合は statement-like になり、then 分岐は効果のために評価され、値は捨てられ、式全体は () を返す。
elsif
elsif は if と else の間に条件を追加する。 条件は左から順に試され、最初に真になった分岐が選ばれる。 すべて偽なら else が選ばれる。
my size n =
if n < 0: "negative"
elsif n == 0: "zero"
elsif n < 10: "small"
else: "large"
say (size 7)case
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 へ進む。
my sign n = case n:
value if value < 0 -> "negative"
value if value == 0 -> "zero"
_ -> "positive"
say (sign 3)catch
act console:
our read: () -> str
catch console::read():
console::read(), k -> k "42"
value -> valueoperation arm は operation の payload と continuation k を受け取る。 k value を呼ぶと計算を再開する。 value arm は通常終了を処理する。
guard
catch の guard は operation pattern と continuation の後ろに if または where で書く。 guard が偽ならその arm は選ばれず、次にマッチする arm が試される。
act signal:
our ask: () -> int
my result = catch signal::ask():
signal::ask(), k if false -> 0
signal::ask(), k -> k 42
value -> value
say resultcase と catch のラベル
case 'label value: と catch 'label action: は arm 集合全体に再帰名を付ける。 label は個々の arm ではなく、arm 集合に属する。 body から 'label next を呼ぶと、同じ case または catch の arm が next に再適用される。
my result = case 'count 3:
0 -> "done"
n -> 'count (n - 1)
say result同じ綴りで labelled catch に再入できる。
my result = catch 'again 3:
n if n > 0 -> 'again (n - 1)
n -> n
say resultfor
for x in 0..10: // 11 回反復: 0..10 は閉区間 (半開は 0..<10)
say xfor x in xs: は Fold を実装する値を走査する。 body は関数へ lower され、plain な for expression は () を返す。
ループ制御は prelude から入る。
for x in 0..:
if x == 10: lastlast、next、redo は、現在のループから抜ける、次の反復へ進む、反復をやり直すための操作である。
ラベル
for 'outer x in 0..:
for y in 0..:
if y == 3: last 'outerlabelled ループは label 値を body に渡す。 last 'outer、next 'outer、redo 'outer は、その label のループを対象にする。
sub と return
sub:
for x in 0..:
if x == 5: return x
0sub: は早期 return scope を作る。 return value は直近の sub: から抜ける。 nullfix の return は () を返す。
labelled sub もある。
sub 'done:
'done.return 42
0sub、return、last、next、redo は標準ライブラリ / prelude の surface である。 parser 専用 keyword ではない。
Block と Lambda
{
my x = 1
x + 1
}
my inc = \x -> x + 1
my add = \x y -> x + y
(inc 1, add 1 2)block は statement を順に評価し、最後の式を返す。 ラムダは \ で始まり、複数引数は curried 関数として扱われる。