使用';参数';从F#(可观察到的,StartWith)
编辑:请注意,正如Daniel和latkin在下面的回答和评论中所指出的,这个问题涉及到F#中的一个bug,该bug似乎已在2014年初修复 我想为Observable.StartWith写一个咖喱包装。我正在使用预发布的被动扩展2.0和VS11测试版。我想要的结果是使用';参数';从F#(可观察到的,StartWith),f#,F#,编辑:请注意,正如Daniel和latkin在下面的回答和评论中所指出的,这个问题涉及到F#中的一个bug,该bug似乎已在2014年初修复 我想为Observable.StartWith写一个咖喱包装。我正在使用预发布的被动扩展2.0和VS11测试版。我想要的结果是开始时使用:'a->IObservable。最明显的实现方式是: let startWith (value : 'a) (observable : IObservable<'a>)
开始时使用:'a->IObservable
。最明显的实现方式是:
let startWith
(value : 'a)
(observable : IObservable<'a>)
: IObservable<'a> =
Observable.StartWith(observable, [| value |])
让startWith
(价值:a)
(可观察的:可观察的=
可观察的。起始时间(可观察,[|值|])
Observable.StartWith的预期重载为
StartWith,params value:'TSource[]):IObservable围绕泛型param数组的类型推断似乎有问题。即使是不涉及过载解决的简单案例也存在问题:
type A() =
static member M<'T>([<ParamArray>] args: 'T[]) = args
//None of these work
let m1 arg = A.M([|arg|])
let m2 args = A.M(args)
let m3<'T> (args:'T[]) = A.M<'T>(args)
type A()=
静态成员M(arg1、arg2)
设m8(arg1:T)(arg2:T)=A.M(arg1,arg2)
设m9(arg1:'T)=A.M(arg1)
设m10(arg1,arg2)
设m11(arg1,arg2)
围绕泛型参数数组的类型推断似乎有问题。即使是不涉及过载解决的简单案例也存在问题:
type A() =
static member M<'T>([<ParamArray>] args: 'T[]) = args
//None of these work
let m1 arg = A.M([|arg|])
let m2 args = A.M(args)
let m3<'T> (args:'T[]) = A.M<'T>(args)
type A()=
静态成员M(arg1、arg2)
设m8(arg1:T)(arg2:T)=A.M(arg1,arg2)
设m9(arg1:'T)=A.M(arg1)
设m10(arg1,arg2)
设m11(arg1,arg2)
您不需要将单个值
包装到单个元素数组中,以使其匹配可观察的的最后一个paramary
参数。StartWith
,只需标量值即可(可能有助于理解原因)
但是,值的泛型类型
会在Observable.StartWith
的两个可用重载之间产生歧义。可以通过强制执行来消除歧义,方法是将隐式类型的IScheduler
从两个参数重载显式放置到参数列表中,并在值
前面加上前缀,如下所示:
let startWith (value: 'a) observable =
Observable.StartWith(observable, Scheduler.CurrentThread, value)
现在,您的代码应该可以编译并工作了。快速检查可确认这一点:
Observable.Range(1,2)
|> startWith 10
|> fun x -> x.Subscribe(printf "%d ")
按预期输出10 1 2
更新
对于Rx 2.0 beta版,调度程序
参考将略有不同,其余答案保持不变:
let startWith (value: 'a) (observable: IObservable<'a>) =
Observable.StartWith(observable, Concurrency.Scheduler.CurrentThread, value)
让startWith(value:'a)(observable:ioobservable您不需要将单个值
包装到单个元素数组中,以使其匹配observable.startWith的最后一个paramary
参数。只需使用标量值即可(可能有助于理解原因)
但是,value
的泛型类型会在Observable.StartWith
的两个可用重载之间产生歧义。可以通过强制将isScheduler
的隐式类型从两个参数重载显式放置到参数列表中,并在value
之前,如b所示,来消除歧义私奔:
let startWith (value: 'a) observable =
Observable.StartWith(observable, Scheduler.CurrentThread, value)
现在,您的代码应该可以编译并运行了。快速检查可以确认这一点:
Observable.Range(1,2)
|> startWith 10
|> fun x -> x.Subscribe(printf "%d ")
按预期输出10 1 2
更新
对于Rx 2.0 beta版,调度程序
参考将略有不同,其余答案保持不变:
let startWith (value: 'a) (observable: IObservable<'a>) =
Observable.StartWith(observable, Concurrency.Scheduler.CurrentThread, value)
让startWith(value:'a)(observeable:iobservable但是对于m
具有'T
-单个参数的-let m(arg:'T)=a.m(arg)
,调用将(几乎)正确工作,因此m5
将返回[\code>5 |]
。同样a.m()
方法本身按预期处理可变长度参数列表:A.M(1,2,3,4,5)
返回[[1;2;3;4;5]
。我能发现的唯一特性是A.M([1;2])
返回[[1;2]
而不是预期的[[1;2]。]
。建议的解决方法m6
在这种情况下似乎是合适的。以下工作:让startWith(value:'a)(observable:IObservable(observable,value)
,需要所有类型注释。仅供参考-此错误已被修复。请参阅,但调用将起作用(几乎)对于m
具有单个参数'T
-让m(arg:'T)=A.m(arg)
,因此m5
将返回[| 5 |]
。此外A.m()
方法本身按预期处理可变长度参数列表:A.m(1,2,3,4,5)
返回
。我能发现的唯一特质是A.M([|1;2 |])
返回[|1;2 |]
而不是预期的[|1;2 |]
。建议的解决方法m6
在这种情况下似乎是合适的。以下工作:让startWith(值:'A)(可观察的:IObservable(可观察的,值)
,需要所有类型注释。仅供参考-此错误已被修复。请至少参阅Rx 2.0 beta版,您的函数不起作用;无论出于何种原因,编译器选择双参数重载并将'a
约束为CurrentThreadScheduler
类型。使用非静态成员函数可以:让star运行tWith(值:'a)(可观察:iobservable至少在Rx 2.0 beta中,您的函数不工作;无论出于何种原因,编译器选择两个参数重载并将'a
约束为CurrentThreadScheduler
类型。使用非静态成员函数工作:let startWith(值:'a)(可观察:iobservable围绕泛型param数组的类型推断有些奇怪。我给fsbug发了电子邮件,会让你知道答案。F#团队确认这是一个bug。我在回答中包括了他们建议的解决方法。这不太可能在F#3.0中得到修复。围绕泛型param数组的类型推断有些奇怪aram阵列。我通过电子邮件发送了fsbugs,并会让您知道响应。F#团队确认这是一个bug。我在回答中包括了他们建议的解决方法。这不太可能在F#3.0中得到修复。