У вас, похоже, есть неправильные впечатления от работы оператора трубы, поэтому я попытаюсь их очистить.
Давайте делать вещи проще напечатать, и сказать, что мы имеем функции Foo и бар:
let foo (a, b, f) = f a b
let bar a b f = f a b
foo
имеет более или менее ту же форму, Observable.Zip и принимает кортеж в качестве аргумента (это как Функции C# видны в F #), bar
- это то же самое, но в карри.
Это работает:
foo (ob1, ob2, fun a b -> a + b)
bar ob1 ob2 (fun a b -> a + b)
Это не работает:
ob1 |> bar ob2 (fun a b -> a + b)
Это потому, что оператор труба делает, принимает значение слева, и передавая его как последний аргумент функции справа. Вы должны были бы бар, чтобы определить, как это:
let bar b f a = f a b
Именно поэтому функции, например, в модуле List определены таким образом, что фактический список передается в качестве последнего аргумента - что делает конвейерной работы в хороший способ.
Это также не работает:
ob1 |> foo (ob2, fun a b -> a + b)
Помимо предыдущей задачи, она также потребует оператора трубы, чтобы заглянуть внутрь кортежа и прикрепить значение там, и это на самом деле не так, как это работает. Кортеж - это одно значение в F #.Функция, которая будет работать для этого примера, будет такой:
let foo (b, f) a = f a b
Но ясно, что это не то, что мы хотим.
Вы все еще можете использовать Observable.Zip в моде трубопровода, как это:
ob1 |> fun x -> Observable.Zip(x, ob2, Func<_,_,_> (fun a b -> a + b))
Или просто пойти с оберткой другого ответа наводит на мысль.
просто используйте это (или скопируйте): https://github.com/fsprojects/FSharp.Reactive/blob/master/src/Observable.fs - btw: проблема в том, что Zip не является точной функцией – Carsten
@ CarstenKönig Пожалуйста, обратите внимание на отправку определения функции 'zip' из модуля в качестве ответа! –
Почему нет - я надеюсь, что у меня нет ошибок там (прямо сейчас на Linux/mono, и я как-то не могу получить Rx Nuget прямо сейчас :() – Carsten