duckmap真的做了什么?

jjm*_*elo 11 recursion functional-programming duck-typing perl6 map-function

文档中

duckmap将对每个元素应用和阻止,并返回一个新的列表,其中包含块的已定义返回值.对于未定义的返回值,如果该元素实现了Iterable,则duckmap将尝试进入该元素.

但是之后:

my $list = [[1,2,3],[[4,5],6,7]];

say $list.deepmap( *² ); # [[1 4 9] [[16 25] 36 49]]
say $list.duckmap( *² ); # [9 9]
Run Code Online (Sandbox Code Playgroud)

deepmap的表现与预期相似,但我无法理解duckmap正在做什么.这个问题与perl6/doc中的这个问题有关.它可以通过"它们无法更加不同"来解决,但我想找到一些例子,他们也会这样做,当他们不这样做时,试着去了解真正发生的事情.

Bra*_*ert 8

duckmap鸭打字 ; 那就是"如果它像鸭子一样走路,像鸭子一样说话,那一定是鸭子."

> say [1,2.2,"3.4",4,"a"].duckmap(-> Str $_ { use fatal; .Int }).perl
[1, 2.2, 3, 4, "a"]
Run Code Online (Sandbox Code Playgroud)

(use fatal是否存在"a".Int故障对象成为抛出异常,因此duckmap捕获它并返回原始数据)

这对于更改输入的一小部分非常有用,而无需专门处理每个可能的输入.

> say [1,2.2,"3.4",4,"a"].map(-> $_ { $_ ~~ Str ?? .Int // .self !! .self }).perl
[1, 2.2, 3, 4, "a"]
> say [1,2.2,"3.4",4,"a"].deepmap(-> $_ { $_ ~~ Str ?? .Int // .self !! .self }).perl
[1, 2.2, 3, 4, "a"]
Run Code Online (Sandbox Code Playgroud)

还有更多的之间的差异duckmap的其他与mapS中,但大家都在为这个基本前提.


> [ [<a b c>], [1,2,3], [[4,5,6],] ].duckmap(-> @_ where .all ~~ Int { @_.Str } ).perl
[["a", "b", "c"], "1 2 3", ["4 5 6"]]

> [ [<a b c>], [1,2,3], [[4,5,6],] ].map(-> @_ { @_.all ~~ Int ?? @_.Str !! @_.self } ).Array.perl
[["a", "b", "c"], "1 2 3", [[4, 5, 6],]] # doesn't match, as map is one level deep
Run Code Online (Sandbox Code Playgroud)

(请注意,你不能完全执行上述操作deepmap,因为它太深了)
为了获得相同的行为map,需要更多的工作.