【问题标题】:What does duckmap really do?鸭图到底是做什么的?
【发布时间】:2018-10-16 12:56:22
【问题描述】:

来自the documentation

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

然后:

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 raku map-function duck-typing


【解决方案1】:

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

> 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 中获得相同的行为,可能需要更多的工作。

【讨论】:

    【解决方案2】:

    duckmap 只有当 &amp;block 不能在 Array 上调用时才会深入。 $_ 可以是-&gt; $_ { $_² } 中的数组。

    试试

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

    在那里,duckmap 深入。

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 2013-09-02
      • 2014-01-02
      • 2013-10-10
      • 2017-05-08
      • 2022-01-20
      • 2012-10-17
      • 2017-06-15
      • 2011-05-20
      相关资源
      最近更新 更多