当我使用名称将动词作为自变量传递给副词时,我得到了一个意外的value error
。
副词(具有谓词u
和边界x
的整数二元搜索(:
bsearch=: adverb define
r=. y NB. range
while. ~:/ 1 0 + r do.
n=. ([: -: ] - 2&|) +/r NB. next
r=. n (u n)}r
end.
{.r
)
一些工作代码:
>&3 bsearch 1 11
3
works=: monad define
r=. 1,y
>&3 bsearch r
)
works 11
3
现在是令人惊讶的行为:
breaks=: monad define
p=. >&3
r=. 1,y
p bsearch r
)
breaks 11
|value error: p
| r=.n( u n)}r
设置停止和调试显示p bsearch r
(动词-副词-名词(处的预期名称类。
reset=: 13!:0
reset 1
13!:3'breaks 2'
breaks 11
|stop: breaks
| p bsearch r
|breaks[2]
4!:0 ;:'p bsearch r'
3 1 0
5!:4<'p'
┌─ >
── & ─┴─ 3
13!:21''
|stop: bsearch
| r=.y
|bsearch[0]
5!:4<'u'
── p
breaks
内部一切如预期。在bsearch
中,动词u
是根据不存在的私有变量p
来定义的。对于更复杂的用例来说,这是完全出乎意料的,而且很难处理。
我用([: p ])
代替p
尝试了一点间接方法,但结果相似。
使用=:
在breaks
中设置p
确实解决了眼前的问题,但这是一个不可行的解决方案。
一种解决方法可能是对bsearch
进行默认定义,这样使用它就不会引入新的范围。我想这可能是我在这里需要的,但我想要一个更通用的解决方案,我想了解为什么我所拥有的不起作用。我想做的是在局部范围内定义一个动词,并将其或从中派生的动词传递给明确定义的副词或连词。
感谢
使用u(和v.表示连词(代替u(和v(。u.与u相似,但它使用调用者的环境。如果您将bsearch定义如下:
bsearch=: adverb define
r=. y NB. range
while. ~:/ 1 0 + r do.
n=. ([: -: ] - 2&|) +/r NB. next
r=. n (u. n)} r
end.
{.r
)
那么它应该做你想做的事。请参阅wiki。