Передача другого параметра в строку в F # - PullRequest
6 голосов
/ 25 февраля 2010

Работает ли параметр передачи в линию только для функций, которые принимают один параметр? Если мы посмотрим на пример на странице Криса Смита ,


// Using the Pipe-Forward operator (|>)
let photosInMB_pipeforward =
    @"C:\Users\chrsmith\Pictures\"
    |> filesUnderFolder
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

где его функция filesUnderFolder ожидала только параметр rootFolder, что если функция ожидает два параметра, то есть
let filesUnderFolder size rootFolder

Тогда это не работает:


// Using the Pipe-Forward operator (|>)
let size= 4
let photosInMB_pipeforward =
    @"C:\Users\chrsmith\Pictures\"
    |> filesUnderFolder size
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

Так как я могу определить
let inline (>>) f g x y = g(f x y)
Я думаю, что я должен быть в состоянии использовать оператор конвейера с функциями, имеющими несколько входных параметров, верно? Чего мне не хватает?

Ответы [ 3 ]

14 голосов
/ 25 февраля 2010

При смешивании операторов конвейера и аргументов карри следует учитывать порядок передачи аргументов.

let size = 4
let photosInMB_pipeforward =
    size, @"C:\Users\chrsmith\Pictures\"
    ||> filesUnderFolder
    |> Seq.map fileInfo
    |> Seq.map fileSize
    |> Seq.fold (+) 0L 
    |> bytesToMB

Думайте об этом, как будто компилятор помещает скобки вокруг функции и ее параметров, как это.

@"C:\Users\chrsmith\Pictures\" |> filesUnderFolder size
становится
@"C:\Users\chrsmith\Pictures\" |> (filesUnderFolder size)
или
(filesUnderFolder size) @"C:\Users\chrsmith\Pictures\"

Пример не в порядке

let print2 x y = printfn "%A - %A" x y;;

(1, 2) ||> print2;;
1 - 2

1 |> print2 2;;
2 - 1

С тремя аргументами

let print3 x y z = printfn "%A - %A - %A" x y z;;

(1, 2, 3) |||> print3;;
1 - 2 - 3

(2, 3) ||> print3 1;;
1 - 2 - 3

3 |> print3 1 2;;
1 - 2 - 3

Определения

let inline (|>) x f = f x

let inline (||>) (x1,x2) f = f x1 x2

let inline (|||>) (x1,x2,x3) f = f x1 x2 x3
9 голосов
/ 25 февраля 2010

Пример, который вы предложили, должен работать нормально, а

let add x y = x + y

41
|> add 1
|> printfn "%d"

Если filesUnderFolder принимает два аргумента с карри и вы частично применяете его к одному аргументу, вы можете использовать его в конвейере для другого.

(Обратите внимание также на менее известного оператора трубопровода ||>

(41,1)
||> add
|> printfn "%d"

, который берет 2-кортеж и последовательно подает их в следующее.)

1 голос
/ 19 ноября 2015

Это может быть плохой стиль (?), Но вы можете добавить дополнительные параметры в конвейер «с правой стороны»

let h x y z = x + y - z

let sub x y = x - y

let sqr x = x * x

3 |> h <| 2 <| 7
  |> sub <| 23
  |> sqr

// is the same as
sqr (sub (h 3 2 7) 23)
...