5.2. 1-modifiers

    4⊑•type∘•BQN∘⋈¨⊸⊔∧"+-×÷⋆√⌊⌈∧∨¬|≤<>≥=≠≡≢⊣⊢⥊∾≍⋈↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜∘○⊸⟜⌾⊘◶⎊⎉˘⚇¨⌜⍟⁼´˝`"
"`¨´˘˙˜˝⁼⌜"

Try it online⌨️

Undo ''の話は書いておきたい。

Fold '´'

Fold '´' は以下のように展開される。

    F´ a‿b‿c‿d‿e → a F b F c F d F e

BQNは右から関数評価を行うことを思い出せば、これは右からのscanである事がわかる。 リストの先頭からのscanではないので、そうしたければF´⌽というフレーズが必要になる。

この延長で初期値𝕨が与えられた場合は以下のように展開される。

    𝕨 F´ a‿b‿c‿d‿e  → a F b F c F d F e F 𝕨
    𝕨 F´⌽ a‿b‿c‿d‿e → e F d F c F b F a F 𝕨

Fの引数の一つをアキュムレーターだとすると直感に反してそれは右引数𝕩に対応するので注意すること。

    10{item F sum : item+10×sum}´⌽3‿5‿7   # 10を初期値とするアキュムレーターsumは左引数
10357
    10{𝕨+10×𝕩}´⌽3‿5‿7    # 簡略版:アキュムレーターは𝕩
10357

uncurryとの関係

右引数がlength=2のリストに対するFoldを改めて書き下すと以下のようになる。

    F´ a‿b → a F b

Fを二要素からなる1つの「タプル」を受け取る1引数関数だとすると は2引数関数である。 従って´はuncurryの操作そのものである1

ちなみに逆変換curryは以下の通り∘⋈なのだろう。

    𝕨 F∘⋈ 𝕩 → F(𝕨⋈𝕩)
1

BQNのドキュメントにはこの関係について明記されてないのだが、興味を持った人が最初に見るであろうA quick start to BQNの最初の変数定義式(L5)にこの変換が出てくる。言われなくても気づけるものなのだろうか。

Cells '˘'

配列の要素に対するmapではなく配列のmajor cellに対してmapを行う。 配列がrank=nの場合、major cellはrank=n-1の配列に相当し、配列はあたかもmajor cellのリストと見なされる。

返値は配列になるので同じshapeを持つ事が要求される。

The Cells modifier ˘ applies a function to major cells of its argument, much like Each applies to elements. Each result from 𝔽 becomes a major cell of the result, which means they must all have the same shape.

    m ← 3‿3⥊↕9
┌─
╵ 0 1 2
  3 4 5
  6 7 8
        ┘
    -∘¬¨m        # 各要素に対するdecrement
┌─
╵ ¯1 0 1
   2 3 4
   5 6 7
         ┘
    -∘¬˘m        # major cellに対するdecrementだがrank多相により各要素に対するdecrementに帰着
┌─
╵ ¯1 0 1
   2 3 4
   5 6 7
         ┘
    +´˘m         # mにおいてはmajor cellは数値のリストに対応するのでfold可能
⟨ 3 12 21 ⟩
   (↕+´)˘m       # しかし長さが違うリストを返そうとするとエラー
Error: ˘: Incompatible result shapes (encountered shapes ⟨3⟩ and ⟨12⟩)
at (↕+´)˘m
   ^^^^^^
   (¯3↑·↕+´)˘m    # shapeが同じなら問題ない
┌─
╵  0  1  2
   9 10 11
  18 19 20
           ┘

条件分岐

else節を持たない1方向分岐は引数𝕩に対して𝔽𝕘回繰り返し適用するRepeat '' で実装できる。

多方向分岐はリスト𝕘𝕗番目の関数を𝕩に対して適用するChoose '' で実装できる。

他には条件分岐のblockが使える。

•_timed (CBQN)

実行時間を測るならこれか)profile

In BQN matrix, someone uses the F0 to compute the largest group of 1s.

    #!/usr/bin/env cbqn
    F0 ⇐ (0⌈´(-˜˝˘∘‿2⥊0⊸(/∾≠∾˜)))
    F1 ⇐ {F s: ⊑0‿0{((⊑𝕩)⊸⌈⋈𝕨⊸×)𝕨+1⊑𝕩}´s}
    F2 ⇐ {⌈´-˜´˘∘‿2⥊/≠´˘2↕0∾𝕩}
    # F2 ⇐ {⌈´-˜´˘∘‿2⥊/≠´˘2↕0∾𝕩∾⟨0⟩}
    seq ⇐ (100×1000×1000) •rand.Range 2
    •Show "F0"⊸⋈ 10 F0•_timed seq
    •Show "F1"⊸⋈ 2 F1•_timed seq
    •Show "F2"⊸⋈ 10 F2•_timed seq
functiontime by •_timed
F00.0916479
F15.9444225
F20.3276033

1-modifier glyphの出現頻度

4.3での計算を基にした1-modifiersの出現頻度は以下の通り。

    •Show>>1⊏s4
┌─
╎ 3400 "¨"
  2481 "´"
  1527 "˜"
  793  "˘"
  549  "`"
  508  "⌜"
  263  "˝"
  258  "⁼"
  201  "˙"
           ┘