4.7 KiB
特殊形式
特殊形式は、Ergの型システムでは表現ができない演算子、サブルーチン(のようなもの)である。``で囲っているが、実際は捕捉できない。
また、Pattern
やBody
, Conv
といった型が便宜上登場するが、そのような型が存在するわけではない。その意味もコンテクストによって異なる。
=
(pat: Pattern, body: Body) -> NoneType
bodyをpatに変数として代入する。同じスコープにすでに変数が存在する場合と、patにマッチしなかった場合にエラーを送出する。 また、レコードの属性定義やデフォルト引数にも使われる。
record = {i = 1; j = 2}
f(x: Int, y = 2) = ...
bodyが型か関数であるときに=
は特殊な振る舞いをする。
左辺の変数名を右辺のオブジェクトに埋め込むのである。
print! Class() # <class <lambda>>
print! x: Int -> x + 1 # <function <lambda>>
C = Class()
print! c # <class C>
f = x: Int -> x + 1
print! f # <function f>
g x: Int = x + 1
print! g # <function g>
K X: Int = Class(...)
print! K # <kind K>
L = X: Int -> Class(...)
print! L # <kind L>
=
演算子は、戻り値が「未定義」である。
多重代入、関数中での=
は文法エラーとなる。
i = j = 1 # SyntaxError: multiple assignments are not allowed
print!(x=1) # SyntaxError: cannot use `=` in function arguments
# hint: did you mean keyword arguments (`x: 1`)?
if True, do:
i = 0 # SyntaxError: A block cannot be terminated by an assignment expression
->
(pat: Pattern, body: Body) -> Func
無名関数、関数型を生成する。
=>
(pat: Pattern, body: Body) -> Proc
無名プロシージャ、プロシージャ型を生成する。
.
(obj, attr)
objの属性を読み込む。
|>
(obj, c: Callable)
c(obj)
を実行する。x + y |>.foo()
は(x + y).foo()
と同じ。
(x: Option T)?
-> T
後置演算子。x.unwrap()
を呼び出し、エラーの場合はその場でreturn
する。
match(obj, ...arms: Lambda)
objについて、パターンにマッチしたarmを実行する。armは無名関数でなくてはならない。
match [1, 2, 3]:
(l: Int) -> log "this is type of Int"
[[a], b] -> log a, b
[...a] -> log a
# (1, 2, 3)
型指定によって処理を分岐できるが、型推論の結果は分岐に影響しない。
zero: {0} -> {0}
one: {1} -> {1}
_ = match x:
i -> zero i
j -> one j # Warning: cannot reach this arm
Del(x: ...T) -> NoneType
変数x
を削除する。ただし組み込みのオブジェクトは削除できない。
a = 1
Del a # OK
Del True # SyntaxError: cannot delete a built-in object
do(body: Body) -> Func
引数なしの無名関数を生成する。() ->
の糖衣構文。
do!(body: Body) -> Proc
引数なしの無名プロシージャを生成する。() =>
の糖衣構文。
else
(l, r) -> Choice
Choiceオブジェクトという2つ組のタプルのような構造体を生成する。
l, r
は遅延評価される。すなわち、.get_then
または.get_else
が呼ばれたとき初めて式が評価される。
choice = 1 else 2
assert choice.get_then() == 1
assert choice.get_else() == 2
assert True.then(choice) == 1
集合演算子
[]
(...objs)
引数から配列、またはオプション引数からディクトを生成する。
{}
(...objs)
引数からセットを生成する。
{}
(...fields: ((Field, Value); N))
レコードを生成する。
{}
(layout, ...names, ...preds)
篩型を生成する。
...
入れ子になったコレクションを展開する。パターンマッチでも使える。
[x, ...y] = [1, 2, 3]
assert x == 1 and y == [2, 3]
assert [x, ...y] == [1, 2, 3]
assert [...y, x] == [2, 3, 1]
{x; ...yz} = {x = 1; y = 2; z = 3}
assert x == 1 and yz == {y = 2; z = 3}
assert {x; ...yz} == {x = 1; y = 2; z = 3}
仮想演算子
ユーザーが直接使用できない演算子です。
ref(x: T) -> Ref T
オブジェクトの不変参照を返す。
ref!(x: T!) -> Ref! T!
可変オブジェクトの可変参照を返す。