我想将一些C#for 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&LT;' TResult&GT;(开始: Func&lt; AsyncCallback,obj,IAsyncResult&gt;,end: Func&lt; IAsyncResult,'TResult&gt;):Func&lt; IObservable&lt;'TResult&gt;&gt;'。
错误3可能的过载: 'Observable.FromAsyncPattern&LT;' T1'TResult&GT;(开始: Func&lt;'T1,AsyncCallback,obj,IAsyncResult&gt;,end: Func&lt; IAsyncResult,'TResult&gt;):Func&lt;'T1,IObservable&lt;'TResult&gt;&gt;'。
似乎F#中的编译器没有识别出过载,但我不知道如何使F#编译器更聪明地完成它的工作。 请告诉我你的代码。 谢谢,周末愉快。 约翰
答案 0 :(得分:3)
问题是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))
)。 / p>
在你的情况下,我认为
let read = Observable.FromAsyncPattern(
(fun a b c d e -> inputStream.BeginRead(a,b,c,d,e)),
fun r -> inputStream.EndRead r)
应该有用。