Semantics of “>>” operator in F#

2020-03-26 05:55发布

问题:

In Microsoft's F# samples, they use the ">>" operator as follows:

test |> Seq.iter (any_to_string >> printfn "line %s");

What does the ">>" operator do in this context? Is each item of the sequence (an array in this case) get passed to any_to_string implicitly? Is this similar to (fun item -> printfn "line %A" item)?

回答1:

An equivalent piece of code could be written the following way:


test |> Seq.iter(fun x -> printfn "line %s" (any_to_string x))

In other words, the >> operator simply does this: given a function f(x) returning type T and g(y) with y being of type T, you can use f >> g to create a function h(z) being equivalent to g(f(x)). No argument but the inner and outer function has to be passed to that operator and the result is a function which can be applied at any time in your code, so you could do this:


//myFunc accepts any object, calls its ToString method, passes ToString
//result to the lambda which returns the string length. no argument is
//specified in advance
let myFunc = any_to_string >> (fun s -> s.Length)
let test = 12345
let f = 12345.0
//now we can call myFunc just like if we had definied it this way:
//let myFunc (x:obj) = obj.ToString().Length
printfn "%i" (myFunc i)
printfn "%i" (myFunc f)


回答2:

(>>) is a higher order function that takes two functions (with compatible arguments) and combines ("composes") them into one function.

For instance with

let len (s : string) = s.Length
let show (n : int) = n.ToString()

The line

(show >> len) 15

is equivalent to

len (show 15)

as well as

show 15 |> len


回答3:

The definition at

http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.Operators.html

says

val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)
//Compose two functions, the function on the left being applied first

But I hope others will provide a more in-depth explanation.

EDIT

MSDN doc now at

http://msdn.microsoft.com/en-us/library/ee353825(VS.100).aspx



回答4:

It's a function composition operator (as described in the other posts)

You can define this operator by yourself in order to see his semantics:

let (>>) f g = fun x -> g (f x)


回答5:

This may be no help at all if you are uncomfortable with C#, generics, or lambdas, but here is an equivalent in C#:

//Takes two functions, returns composed one
public static Func<T1, T2> Compose<T1, T2, T3>(this Func<T1, T2> f, Func<T2, T3> g)
{
    return (x) => g(f(x));
}

Looking at the type parameters reads something like Brian's answer:

Compose takes one function that goes from T1 to T2, and another that goes from T2 to T3, and returns the combination of the two, which goes from T1 to T3.



回答6:

The >> operator performs function composition, which is explained quite nicely on Wikipedia. Dustin Campbell provides a great use for it and explains it (along with the |> (forward pipe) operator) on his blog.