rslt ← i j k ··· F ##.case G case H ··· arg ⍝ Select statement.
i j k ··· is a simple boolean vector whose length is the number of monadic
functions (F G H ···) in the derived function. [case] applies the function
selected by the boolean left argument to the derived function's right argument.
The statement is equivalent to:
:Select 1
:Case i ⋄ rslt←F arg
:Case j ⋄ rslt←G arg
:Case k ⋄ rslt←H arg
:Case l ⋄ rslt←I arg
...
:Else ⋄ rslt←arg
:End
The simple alternating pattern of ... fn op fn op fn ... in the statement hides
the fact that the functions are at different "depths" in the derived function.
For illustration the derived fn (f05) below has two operands to the "topmost"
compose operator; the right being (÷) and the left, all the rest (⌈∘⌊∘-∘×)
f05←⌈∘⌊∘-∘×∘÷ ⋄ ⎕cr'f05'
┌───────────────┬─┬─┐
│┌─────────┬─┬─┐│∘│÷│
││┌───┬─┬─┐│∘│×││ │ │
│││⌈∘⌊│∘│-││ │ ││ │ │
││└───┴─┴─┘│ │ ││ │ │
│└─────────┴─┴─┘│ │ │
└───────────────┴─┴─┘
Similarly in fns derived with (case), only (⍵⍵) is necessarily available for
immediate use so we run (⍵⍵) if the last of (⍺) is set. If not, and if (⍺) has
length 2 and the first is one we can run (⍺⍺), which must be at the "top" level.
cf. (⌈∘⌊) in (f05) above. If there are more than two items in (⍺), (⍺⍺) must be
derived with another (case) call so we run it dyadically losing the last (⍺).
A no-guard one-liner using conditional monad-reduction (see →pow←) is possible.
case←{⊃⍺⍺{b ⍺⍺ ⍵}/(i~∨/b←¯1↓b),⍺⍺{⍺⍺ ⍵}/(⍳i←1 0≡b),⍵⍵{⍺⍺ ⍵}/(⍳¯1↑b←<\⍺),⊂⍵}
Examples:
1 0 0 0 + case - case × case ÷ 10 ⍝ +10
10
0 1 0 0 + case - case × case ÷ 10 ⍝ -10
¯10
0 0 1 0 + case - case × case ÷ 10 ⍝ ×10
1
0 0 0 1 + case - case × case ÷ 10 ⍝ ÷10
0.1
0 0 0 0 + case - case × case ÷ 10 ⍝ 10 (no case selected).
10
See also: for of Function_arrays pow co_ops
Back to: contents
Back to: Workspaces