В F#, что означает конвейерная обработка?

Я читал эту статью Tomas Petricek, и она упомянула конвейерную обработку |> как в данном примере:

> let nums = [1; 2; 3; 4; 5];;
val nums : list<int>

> let odds_plus_ten = 
        nums
        |> List.filter (fun n-> n%2 <> 0)
        |> List.map (add 10)
val odds_plus_ten : list<int> = [11; 13; 15];;

Что означает конвейерная обработка? Первоначально, я думал, что это было сродни инструкции по ЦП, конвейерной в ядрах. Можно ли объяснить, что это и как это работает в контексте F#?

Спасибо, С наилучшими пожеланиями, Tom.

8
задан t0mm13b 1 February 2010 в 13:58
поделиться

4 ответа

Трубопровод означает, что передает результаты одной функции в другую функцию. В примере вы даете «NUMS», пропускается список. Фильтрующий результаты затем передаются в список.

Подробнее здесь: http://msdn.microsoft.com/en-us/magazine/cc64244.aspx#s6

11
ответ дан 5 December 2019 в 05:26
поделиться

Пара мыслей. Во-первых, для получения небольших групп файлов можно использовать модуль glob . Во-вторых, сортировка по количеству строк займет очень много времени, так как вы должны открыть каждый файл и количество строк. При возможности секционирования по количеству байтов можно избежать открытия файлов с помощью модуля stat . Если очень важно, чтобы разделение происходило в 20 строках, вы можете, по крайней мере, вырезать большие фрагменты файлов, выяснив минимальное количество символов, которое будет иметь файл 20 строк вашего типа, и не открывая файл меньше этого.

-121--4407479-

Вы можете использовать www.google.co.uk напрямую, без разницы. google.com/.net всегда перенаправляете в ваше местоположение, но если вы используете TLD страны, такой как .co.uk это не будет перенаправлять.

Не существует способа (известного мне) предотвратить перенаправление при использовании .com или .net.

-121--2501910-

В некоторых отношениях нет ничего особенного в трубопроводе; вместо записи f (g (h x)) можно написать x | > h | > g | > f , что не кажется очевидным улучшением. Однако есть два момента, которые стоит помнить:

  1. Иногда порядок чтения лучше для конвейерной версии: «Возьмите и отправьте его в h, отправьте результат в g, отправьте результат в f» может быть легче понять, чем «Применить f к результату применения g к результату применения h к x».
  2. Вывод типа часто работает намного лучше для конвейерной версии. Это, вероятно, самая большая причина того, что конвейерная обработка используется так много в F #. Поскольку вывод типа продолжается слева направо, x | > Array.map (fun s - > s.Length) будет работать, когда x является последовательность [] , но Array.map (fun s - > s.Length) x не будет; Вместо этого необходимо выполнить Array.map (fun (s: последовательность) - > s.Length) x .
15
ответ дан 5 December 2019 в 05:26
поделиться

Как упомянуты другие, трубопроводы больше похоже на конвейер Unix Shell. Это давайте напишите некоторые входные данные, а затем операции, которые следует применять к нему, вместо обычных вложенных вызовов функций. В этом примере стандартный код F # будет выглядеть так:

let r = List.map (add 10) (List.filter (fun n-> n%2 <> 0) nums)

Обратите внимание, что вход nums , глубоко вложен в экспрессии, и его нелегко видеть, что он сначала фильтруется, а затем проецируется. Используя трубопровод, вы можете написать код по-разному, но это будет означать точно так же.

Хитрость заключается в том, что оператор трубопроводов принимает два параметра с использованием записи инфикса (например, x |> f ). Параметр x будет передан как последний аргумент функции справа ( f ). Вы можете использовать Pibelining с любыми функциями F #:

let sinOne = 1.0 |> sin

let add a b = a + b
let r = 10 |> add 5 // it doesn't always make code more readable :-)

Важная точка о том, что оператор по эксплуатации F # - это то, что он не является какой-либо специальной встроенной функцией языка. Это простой пользовательский оператор, который вы можете определить самостоятельно:

let (|>) x f = f x

// Thanks to operator associativity rules, the following:
let r = 1.0 |> sin |> sqrt
// ...means this:
let r = (1.0 |> sin) |> sqrt
3
ответ дан 5 December 2019 в 05:26
поделиться

Проверьте Pipelining в F # для объяснения.

(Если вы знакомы с командной строкой Unix и трубами, такими как

cat file1 | sort | head 

, это аналогичная идея; результат предыдущего выражения становится аргументом следующей функции.)

2
ответ дан 5 December 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: