3

在 Microsoft 的F# 示例中,它们使用“>>”运算符,如下所示:

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

“>>”运算符在这种情况下做了什么?序列的每个项目(在这种情况下是一个数组)是否被any_to_string隐式传递给?这类似于(fun item -> printfn "line %A" item)吗?

4

6 回答 6

8

(>>)是一个高阶函数,它接受两个函数(具有兼容的参数)并将它们组合(“组合”)为一个函数。

例如与

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

线

(show >> len) 15

相当于

len (show 15)

show 15 |> len
于 2009-05-13T17:01:25.703 回答
5

定义在

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

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

但我希望其他人能提供更深入的解释。

编辑

MSDN 文档现在在

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

于 2009-05-13T16:53:47.603 回答
5

可以通过以下方式编写等效的代码:


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

换句话说,>> 运算符只是这样做:给定一个函数 f(x) 返回类型 T 和 g(y),其中 y 是类型 T,你可以使用 f >> g 创建一个函数 h(z)相当于 g(f(x))。没有参数,但必须将内部和外部函数传递给该运算符,结果是一个可以随时在您的代码中应用的函数,因此您可以这样做:


//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)
于 2009-05-13T16:59:41.807 回答
3

这是一个函数组合运算符(如其他帖子中所述)

您可以自己定义此运算符以查看其语义:

let (>>) f g = fun x -> g (f x)
于 2009-05-13T17:06:55.603 回答
3

如果您对 C#、泛型或 lambdas 感到不舒服,这可能根本没有帮助,但这里有一个 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));
}

查看类型参数的内容类似于 Brian 的回答:

Compose 采用一个从 T1 到 T2 的函数,另一个从 T2 到 T3 的函数,并返回从 T1 到 T3 的两者的组合。

于 2009-05-14T08:05:26.330 回答
2

运算符执行功能组合,这在 Wikipedia 上>>有很好的解释。Dustin Campbell 提供了一个很好的用途,并在他的博客上解释了它(连同(正向管道)运算符)。|>

于 2009-05-13T16:59:14.583 回答