Как сделать что-то функционально со всеми элементами списка в Perl 6? - PullRequest
0 голосов
/ 27 сентября 2018

Например, у меня есть Array с числами:

> my @a = ^5
[0 1 2 3 4]

, и я хочу напечатать их квадраты.Я могу использовать map, но он также вернет измененный List (эти пять True с), который мне не нужен:

> @a.map({ put $_**2 })
0
1
4
9
16
(True True True True True)

Единственный способ, который я нашел, этоиспользовать hyper >>:

> @a>>.&{ put $_**2 }
0
1
4
9
16

но

  • синтаксис немного неуклюжий (вероятно, я делаю это не так, как предполагалось)
  • что еслиЯ не хочу, чтобы он работал с hyper?

Так, как правильно это сделать?

PS Конечно, я могу использовать map, а затемput результат:

.put for @a.map: {$_**2 }

но это не то, что я хочу.

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Этот ответ дополняет другие ответы.Я буду бродить вокруг вашего вопроса, предполагая, что вы и другие читатели заинтересованы в некоторых возможностях подхода FP ish , который избегает пуризма.

my @a = ^5;            # @a bound to an Array
@a.map(* ** 2)  .put;  # 0 1 4 9 16
@a.put;                # 0 1 2 3 4       <- Array unchanged

@a.map(* **= 2) .put;  # 0 1 4 9 16
@a.put;                # 0 1 4 9 16      <- Array changed

@a := @a.List;         # rebind @a to a List
@a.map(* ** 2)  .put;  # 0 1 16 81 256   <- Same as if Array
@a.put;                # 0 1 4 9 16      <- List unchanged

@a.map(* **= 2) .put;  # Cannot assign to an immutable value

Примеры Array показываюткак вы можете по желанию мутировать в пассиве.(Он делает это, используя бинарный (инфиксный) оператор в форме op= вместо просто op, но если это сбивает с толку, просто обратите внимание на эффект и игнорируйте синтаксис.)

En Пассивная мутация является гораздо более«злой» побочный эффект, чем простой, такой, что пурист был бы в некотором роде ужасен, если бы кто-то назвал его «функциональным» стилем.Не я конечно.:)

И пример List идет в другом направлении, двигаясь к неизменности.List s являются неизменными wannabes .

Опять же, те, кто в FP, вероятно, будут хвалить их неизменность.Пуристы очерняют аспект подражателей.Народ Perl, скорее всего, увидит это в обоих направлениях.

Неизменяемые подражатели

A List полностью или в основном неизменны.

Вы никогда не можете пушить или вставлять List.

Его длина всегда неизменна.

Список базовых значений полностью неизменен:

my $really-immutable-list = (1,2,'foo', 1.5, (3,4,5));

Исключением является то, что если элемент списка сам изменчивзатем вы можете изменить его и, таким образом, изменить List:

my $only-shallowly-immutable-list = (1,2,'foo', 1.5, [3,4,5]);
$only-shallowly-immutable-list[4][1] = 9;
say $only-shallowly-immutable-list; # (1 2 foo 1.5 [3 9 5])

Более тонко:

class c { has $.foo; method waldo { $!foo = 42 } }
my $bar  = c.new;
my $list = ($bar, 2);
say $list;   # (c.new(foo => Any) 2)
$bar.waldo; 
say $list;   # (c.new(foo => 42) 2)
0 голосов
/ 27 сентября 2018

Использование map хорошо для этой цели, так как в контексте приемника это не будет производить список результатов.В REPL требуется результат map, поэтому он и создается.Но в случае, подобном:

@a.map({ put $_**2 });
say "That's all, folks";

, тогда результат map не требуется, и поэтому список результатов не будет собран.Если вы действительно хотите объяснить это, можно написать:

sink @a.map({ put $_**2 })

Имейте в виду, что последнее выражение в подпрограмме принимается как неявное возвращаемое значение.Использование --> Nil будет достаточным для обеспечения того, чтобы окончательный map находился в контексте приемника.

sub put-squares(@a --> Nil) {
    @a.map({ put $_**2 })
}
0 голосов
/ 27 сентября 2018

Прежде всего, использование >>. является не хорошей идеей, поскольку заказ , в котором выполняются операции, не гарантированно будетв любом конкретном порядке.

Вы можете использовать WhateverCode:

.say for @a.map: * ** 2

, который лично я считаю наиболее читабельным.В качестве альтернативы вы можете использовать переменную-заполнитель:

.say for @a.map: { $^value ** 2 }

или полностью записать ее:

.say for @a.map: { $_ ** 2 }

Но, очевидно, вы этого не хотите.Почему?

...