Семантика оператора «>>» в F#
Вопрос
В Microsoft Образцы F#, они используют оператор «>>» следующим образом:
test |> Seq.iter (any_to_string >> printfn "line %s");
Что делает оператор «>>» в этом контексте?Передается ли каждый элемент последовательности (в данном случае массив) any_to_string
неявно?Это похоже на (fun item -> printfn "line %A" item)
?
Решение
Эквивалентный фрагмент кода можно написать следующим образом:
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)
Другие советы
(>>)
— это функция более высокого порядка, которая принимает две функции (с совместимыми аргументами) и объединяет («составляет») их в одну функцию.
Например, с
let len (s : string) = s.Length
let show (n : int) = n.ToString()
Линия
(show >> len) 15
эквивалентно
len (show 15)
а также
show 15 |> len
Определение в
говорит
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
Это оператор композиции функций (как описано в других сообщениях).
Вы можете определить этот оператор самостоятельно, чтобы увидеть его семантику:
let (>>) f g = fun x -> g (f x)
Возможно, это вообще не поможет, если вам некомфортно работать с C#, дженериками или лямбда-выражениями, но вот эквивалент на 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));
}
Глядя на параметры типа, можно увидеть что-то вроде ответа Брайана:
Compose принимает одну функцию, идущую от T1 к T2, и другую, идущую от T2 к T3, и возвращает комбинацию этих двух, которая идет от T1 к T3.
А >>
оператор выполняет композицию функций, что довольно хорошо объяснено в Википедии.Дастин Кэмпбелл отлично его использует и объясняет (вместе с |>
(передовая труба) оператор) в его блоге.