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)