在任何APL方言中,条件函数是否有符号或众所周知的习语?
我确定我错过了一些东西,因为它是一种基本的语言元素。在其他语言中,它被称为条件运算符,但我会在这里避免使用该术语,因为APL运算符完全不同。
例如C和朋友有x ? T : F
LISP有(if x T F)
Python有T if x else F
等等。
我知道现代APL有:If
和朋友,但它们是控制程序流的命令性语句:它们不返回值,不能在表达式中使用,当然也不能应用于布尔数组。他们完全有不同的目的,这对我来说很好。
我可以提出的唯一正确的表达方式是(F T)[⎕IO+x]
,虽然它完成了工作,但即使在数组上也不会特别简写或对我来说是可读的:
('no' 'yes')[⎕IO+(⍳5)∘.>(⍳5)]
no no no no no
yes no no no no
yes yes no no no
yes yes yes no no
yes yes yes yes no
我尝试使用小队⌷
提出类似的表达,但在布尔阵列上失败了。即使我可以,它仍然必须嵌入⎕IO
或硬编码1,就可读性而言,这更糟糕。
在我开始定义我自己的if
并在我将要编写的每个程序上使用它之前,有什么经典吗?我错过了一个明显的功能或操作员吗?
(SO上有APL程序员吗?: - )
答案 0 :(得分:10)
这些问题:
(f t)[x]
x⌷f t
x⊃f t
是评估t
和f
。
如果你想短路,你可以使用警卫:
{x:t ⋄ f}
这相当于
if (x) {
return t;
}
f;
用类C语言。
答案 1 :(得分:8)
是的,SO上有APL程序员(但不是很多!)。
我认为答案是没有标准。
对于标量解决方案,我使用“pick”:
x⊃f t
对于布尔数组,我使用索引,如上所述:
f t[x]
我总是使用索引原点零,所以不需要加1,而且不需要parens。
如果这些不够简单,我认为你必须使用名为“if”的函数来覆盖它们。这也可以让你把真假放在t f的更自然的顺序中。
答案 2 :(得分:2)
一个古老的习语,它做了类似C的三元运算符? :
,并返回了一个结果如下:
r←⍎(¯3 3)[x=42]↑'6×8 ⋄ 6×7'
请注意,这是为原点0而写的,为了清楚起见,-3 -3周围的parens是为了清晰。
x = 42的计算结果为零或一,根据这个答案,我们选择-3或3,从而选择并执行字符串的前3个元素(“6x8”)或最后3个元素(“6x7”) 。钻石⋄就在那里装饰。
毋庸置疑,如果有人:if:else avaiable,可能不会以这种方式编码,尽管控制结构形式不会返回结果。
答案 3 :(得分:2)
在Dyalog APL中,您可以使用:
'value if true' (⊣⍣condition) 'value if false'
这个想法是应用⊣
(左侧大头钉 - 它总是返回其左侧参数,同时丢弃正确的参数)0(对于假)或1(对于真)时间 - 到右对齐。因此,如果它被应用0次(即根本不应用),则右参数未经修改地返回,但如果应用(一次),则应用左参数。 E.g:
a b←3 5
Conditional←⊣⍣(a=b)
'match' Conditional 'different'
different
a b←4 4
Conditional←⊣⍣(a=b)
'match' Conditional 'different'
match
或
Cond←{⍺(⊣⍣⍺⍺)⍵}
bool←a=b
'match'(bool Cond)'different'
match
答案 4 :(得分:0)
这是一个常见的问题,我认为没有标准答案的原因是,对于你用APL做的事情,实际上对它的需求比其他语言要少。
也就是说,有时需要它,我在GNU APL中实现IFELSE
运算符的方式是使用这个函数:
∇Z ← arg (truefn IFELSE falsefn) condition ;v
v←⍬
→(0=⎕NC 'arg')/noarg
v←arg
noarg:
→condition/istrue
Z←falsefn v
→end
istrue:
Z←truefn v
end:
∇
可以像这样调用该函数:
3 {'expression is true' ⍵} IFELSE {'was false' ⍵} 0
was false 3
这个特殊的实现将左侧参数作为⍵
传递给子句,因为这有时候很方便。没有左手参数,它会传递到⍬
。
答案 5 :(得分:0)
APL表达:
(1+x=0)⌷y z
应该是
的C语言等价物x?y:z
所有其他人
(1+x>0)⌷y z
代表
x<=0?y:z
等。通常,如果b c是各个语言的表达式,则APL表达式为:
(1+~a)⌷b c
它应该等同于C语言:
a?b:c