Raku 中的 Or Junction
作者:gugod 發佈於: #raku寫了 PWC 080 後經 @holli-holzer 提醒,想說再來用 Or Junction 寫一回好了。
在 解 PWC 080 一文之中,將 N 個整數 @N
做成集合的寫法是:
my @N = @*ARGS.map({ .Int })
my $seen = @N.Set();
這之後,在使用之時,是把 $seen
當成 Hash 在用。以 $seen{$n}
來表示「測看看 $n
是否在 $seen
這個集合中」。
不過,若是以「測看看某個值是否在某個集合類的容器之中」為目的的話,Raku 裡有非常多寫法。以下以整數集合為例來列舉,令 $x
表示要找尋的值,@N
與 $N
表示集合類容器。
if $x (elem) @N { ... }
if $x ∈ @N { ... }
if $x (elem) $N { ... }
if $x ∈ $N { ... }
此列中 @N
為 Array, 而 $N
可為 Seq (無限大的容器)或 Set(有限大的容器)。
Set 這部份另有 Sets, bags, and mixes 這篇文章可以參考。凡是「有限集合」類的容器物件,都可以與 ∈、∉、∋、∌、⊆、⊈、⊂、⊇、⊉、⊃、⊅、∪、∩、∖、⊖、⊍、⊎ 這一套數學符號算符來配合使用。或許對於看慣數學表示法的人而言會有些親切感。
另外一套寫法,就是透過 OR Junction 物件。
any:
# any
if $x == any(@N) { ... }
infix |。|
為一般 US 鍵盤能打出的 pipe 字符。把任何中綴算符放在 [ ]
當中,就可變成前綴算符。例如 1 + 2 + 3 + 4 + 5
亦可表示為 [+] (1..5)
。因此也可利用前綴化的 |
來建立 Junction 物件。
if $x == [|] (1,2,3,4,5) { ... }
if $x == [|] @N { ... }
如果將 Junction 物件存在純量變數中,使用起來就與一般純量無異。
$N = [|] @N;
或寫做:
$N = any(@N);
使用時:
if $x == $N { ... }
或許 Junction 這特性對於功能之延伸與程式碼之重構很有利。
附帶一提,之前寫到的連環比較運算式,也可以透過算符前綴化來將表示式簡化。比方說有一陣列整數 @N
,要確認這陣列是否是完全由小到大排好,可以很苦力地寫出(@N
長度一變就破功):
if @N[0] < @N[1] < @N[2] < @N[3] { ... }
也可寫:
if [<] @N { ... }
這種簡短無比的表示式。