F # RX, преобразующий асинхронные шаблоны в наблюдаемые последовательности - PullRequest
0 голосов
/ 08 января 2012

Я хочу преобразовать немного C # для RX в код F #. Ниже приведен код C #:

Stream inputStream = Console.OpenStandardInput();
var read = Observable.FromAsyncPattern<byte[], int, int, int>    
    (inputStream.BeginRead, inputStream.EndRead);
byte[] someBytes = new byte[10];
IObservable<int> source = read(someBytes, 0, 10);
IDisposable subscription = source.Subscribe(
                        x => Console.WriteLine("OnNext: {0}", x),
                        ex => Console.WriteLine("OnError: {0}",                                   ex.Message),
                        () => Console.WriteLine("OnCompleted"));
Console.ReadKey();

Вот мой код в F #:

#light
open System
open System.Collections.Generic
open System.Linq
open System.Reactive
open System.Reactive.Linq
open System.Reactive.Subjects
open System.Threading
open System.IO

let inputStream: Stream = Console.OpenStandardInput()
let read = Observable.FromAsyncPattern<byte[], int, int, int>(inputStream.BeginRead, inputStream.EndRead)
let someBytes: byte[] = Array.create 10 (byte(0))
let source: IObservable<int> = read(someBytes, 0, 10)

let subscription:IDisposable = 
                 source.Subscribe((fun x -> printfn "OnNext %A" x), 
                               (fun ex -> printfn "OnError %A" ex.Message), 
                               (fun _ -> printfn "OnComplete"))
Console.ReadKey() |> ignore

Но я получил следующие ошибки компилятора:

Ошибка 1 Нет совпадений перегрузок для метода FromAsyncPattern. доступные перегрузки показаны ниже (или в окне списка ошибок).

Ошибка 2 Возможная перегрузка: 'Observable.FromAsyncPattern <' TResult> (начало: Func , конец: Func ): Func > '.

Ошибка 3 Возможная перегрузка: 'Observable.FromAsyncPattern <' T1 'TResult> (начало: Func <'T1, AsyncCallback, obj, IAsyncResult>, конец: Func ): Func <' T1, IObservable <'TResult >>'.

Кажется, компилятор в F # не распознал перегрузку, но я не знаю, как сделать компилятор F # умнее, чтобы выполнять свою работу. Пожалуйста, покажи мне свой код. Спасибо и хороших выходных. John

1 Ответ

3 голосов
/ 08 января 2012

Проблема в том, что аргументы FromAsyncPattern являются делегатами (типа Func<...>), а не функциями F # (типа _->_). Следовательно, вы не можете просто передать метод (например, inputStream.BeginRead), но вам нужно либо передать явную функцию (например, fun a b c d e -> inputStream.BeginRead(a,b,c,d,e)), либо явно создать делегат (например, System.Func<_,_,_,_,_,_>(fun a b c d e -> inputStream.BeginRead(a,b,c,d,e))).

В вашем случае, я думаю, что

let read = Observable.FromAsyncPattern(
            (fun a b c d e -> inputStream.BeginRead(a,b,c,d,e)), 
            fun r -> inputStream.EndRead r)

должно работать.

...