Seq.iter vs for - какая разница?
я могу сделать
for event in linq.Deltas do
или я могу сделать
linq.Deltas |> Seq.iter(fun event ->
Так что я не уверен, что это то же самое. Если это не то же самое, я хочу знать разницу. Я не знаю, что использовать: iter
или for
.
добавил - так что если это вопрос выбора, я предпочитаю использовать iter
на верхнем уровне, а for
для закрытия
добавлено немного позже - похоже, что iter
is map
+ ignore
- это способ использовать слово императивного игнорирования. Так что это выглядит как функциональный способ...
Ответы
Ответ 1
Вы можете изменять изменяемые переменные из тела цикла for
. Вы не можете сделать это из закрытия, что означает, что вы не можете сделать это с помощью iter
. (Примечание: я говорю о изменяемых переменных, объявленных вне for
/iter
. Доступны локальные переменные переменные.)
Учитывая, что точкой iter
является выполнение какого-либо побочного эффекта, разница может быть важной.
Я лично редко использую iter
, поскольку я нахожу for
более понятным.
Ответ 2
Как уже упоминалось, существуют некоторые различия (iter
поддерживает не общие IEnumerator
, и вы можете мутировать значения mutable
в for
). Это иногда важные различия, но в большинстве случаев вы можете свободно выбирать, какой из них использовать.
Обычно я предпочитаю for
(если существует языковая конструкция, почему бы не использовать ее?). Случаи, когда iter
выглядит лучше, когда у вас есть функция, которую вам нужно вызвать (например, с использованием частичного приложения):
// I would write this:
strings |> Seq.iter (printfn "%c")
// instead of:
for s in strings do printfn "%c" s
Аналогично, использование iter
лучше, если вы используете его в конце некоторого конвейера обработки:
// I would write this:
inputs |> Seq.filter (fun x -> x > 0)
|> Seq.iter (fun x -> foo x)
// instead of:
let filtered = inputs |> Seq.filter (fun x -> x > 0)
for x in filtered do foo x
Ответ 3
В большинстве ситуаций они одинаковы. Я бы предпочел первое использование. Мне это ясно.
Разница в том, что for in
поддерживает цикл IEnumerable
, а Seq.iter требует, чтобы ваша коллекция (linq.deltas
) была IEnumerable<T>
.
например. MatchCollection
класс в регулярном выражении .net наследует IEnumerable
not IEnumerable<T>
, вы не можете использовать Seq.map
или Seq.iter
непосредственно на нем. Но вы можете использовать цикл for in
.
Ответ 4
Это стиль программирования. Императив против использования функционального программирования. Имейте в виду, что F # не является чистым функциональным языком программирования.
Как правило, используйте Seq.Iter, если он является частью некоторой большой обработки конвейера, поскольку это делает его намного яснее, но для обычного случая я считаю, что императивный путь более ясен. Иногда это личное предпочтение, иногда это другие проблемы, такие как производительность.
Ответ 5
for
в F # является формой понимания списка - хлеб и масло функционального программирования, а Seq.iter
- это "для сторонних", эффекты только "императивная конструкция" - не признак функционального кода. Вот что вы можете сделать с for
:
let pairsTo n = seq {
for i in [1..n] do
for j in [i..n] do
if j%i <> 0 then yield (i,j) }
printf "%A" (pairsTo 10 |> Seq.toList)