Piping another parameter into the line in F#

跟風遠走 提交于 2019-12-19 07:29:22

问题


Is piping parameter into line is working only for functions that accept one parameter? If we look at the example at Chris Smiths' page,


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

where his filesUnderFolder function was expecting only rootFolder parameter, what if the function was expecting two parameters, i.e.
let filesUnderFolder size rootFolder

Then this does not work:


// 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

Since I can define
let inline (>>) f g x y = g(f x y)
I think I should be able to use pipeline operator with functions having multiple input parameters, right? What am I missing?


回答1:


When mixing pipeline operators and curried arguments be aware of the order you pass arguments with.

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

Think about it as if the compiler is putting parentheses around the function and its parameters like this.

@"C:\Users\chrsmith\Pictures\" |> filesUnderFolder size
becomes
@"C:\Users\chrsmith\Pictures\" |> (filesUnderFolder size)
or
(filesUnderFolder size) @"C:\Users\chrsmith\Pictures\"

Out of order example

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

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

1 |> print2 2;;
2 - 1

With three arguments

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

Definitions

let inline (|>) x f = f x

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

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



回答2:


The example you suggested should work fine, a la

let add x y = x + y

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

If filesUnderFolder takes two curried args, and you partially apply it to one arg, you can use it in the pipeline for the other.

(Note also the lesser known pipeline operator ||>

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

which takes a 2-tuple and feed them sequentially into what follows.)




回答3:


It may be bad style (?), but you can add additional parameters to the pipeline 'from the right side'

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)


来源:https://stackoverflow.com/questions/2330779/piping-another-parameter-into-the-line-in-f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!