Что действительно делает Duckmap? - PullRequest
0 голосов
/ 06 мая 2018

С документация

duckmap будет применять &block к каждому элементу и возвращать новый список с определенными возвращаемыми значениями блока. Для неопределенных возвращаемых значений duckmap попытается спуститься в элемент, если этот элемент реализует Iterable.

Но тогда:

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.

Этот вопрос относится к этой проблеме в perl6 / doc . Это можно решить с помощью «Они не могут быть более разными», но я хотел бы найти несколько примеров, когда они делают то же самое, а когда нет, постарайтесь действительно понять, что происходит.

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

утка в 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 и другими map с, но все они существуют для этой основной предпосылки.


> [ [<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, потенциально потребуется гораздо больше работы.

0 голосов
/ 06 мая 2018

duckmap углубляется, только если &block не может быть вызван на массиве. $_ может быть массивом в -> $_ { $_² }.

Попробуйте

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

Там duckmap углубляется.

...