duckmap真的做了什么?

问题描述 投票:11回答:2

来自the documentation

duckmap将在每个元素上应用&block并返回一个新的列表,其中包含块的定义返回值。对于未定义的返回值,如果该元素实现duckmapIterable将尝试下降到元素中。

但是之后:

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

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

deepmap表现得非常像预期,但我真的无法理解duckmap正在做什么。

这个问题与this issue in perl6/doc有关。它可以通过“它们无法更加不同”来解决,但我想找到一些例子,他们也会这样做,当他们不这样做时,试着去了解真正发生的事情。

recursion functional-programming perl6 map-function duck-typing
2个回答
8
投票

duckmap中的鸭子指的是鸭子打字;那就是“如果它像鸭子一样走路,像鸭子一样说话,那一定是鸭子。”

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

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"]

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

(请注意,你无法使用deepmap完成上述操作,因为它太深了) 为了从map中获得相同的行为,可能需要更多的工作。


3
投票

duckmap只有在无法在阵列上调用&block时才会深入。 $_可以在-> $_ { $_² }中阵列。

尝试

say $list.duckmap( -> Int $_ {$_²} ); #returns [[1 4 9] [[16 25] 36 49]]

在那里,duckmap深入。

© www.soinside.com 2019 - 2024. All rights reserved.