我正在玩一个来自this nice tutorial的f#的简单示例。并遇到了这个非常奇怪的错误。在向webrequest添加代理之后,它告诉我类型WebProxy与预期类型IWebProxy不兼容。这有点奇怪,为什么我的C#锤子在F#中无法工作?
我在这里做错了什么?
let downloadUrlToFile url file =
let req = WebRequest.Create(Uri(url))
req.Proxy = new WebProxy("127.0.0.1", 444)
use res = req.GetResponse()
use stream = res.GetResponseStream()
use reader = new IO.StreamReader(stream)
let timestamp = DateTime.UtcNow.ToString("yyy-MM-dd")
let path = sprintf "%s.%s.html" file timestamp
use writer = new IO.StreamWriter(path)
writer.Write(reader.ReadToEnd())
printfn "done loading %s to %s" url file
错误消息
This expression was expected to have type
IWebProxy
but here has type
WebProxy
答案 0 :(得分:4)
正如其他人已经解释的那样,问题是=
是比较运算符。在这种情况下,您需要一个<-
的作业。
但是,F#实际上会在几种情况下隐式执行upcast,并且赋值就是其中之一,因此您无需添加:> IWebProxy
来转换对象。以下内容可以正常使用:
req.Proxy <- new WebProxy("127.0.0.1", 444)
除了赋值,F#还在将参数传递给方法或函数时进行隐式向上转换。对于比较运算符,它不会这样做(因为你想知道,没有任何歧义,比较什么类型。)
答案 1 :(得分:1)
嗯,至少有两件事,你不希望在这里:
req.Proxy = new WebProxy(...)
是一种比较,您可能需要req.Proxy <- new WebProxy(...)
代替。req.Proxy <- new WebProxy(...) :> _
之类的内容进行静态上传。这告诉F#&#34; upcast到这里适合的任何东西&#34;。(我实际上并没有运行你的代码,所以你可能会有更多的问题,但这两个对于C#程序员来说当然很重要。)
答案 2 :(得分:1)
F#不会像C#那样自动转发值,因此您需要将WebProxy
对象显式地转换为IWebProxy
,如下所示:
req.Proxy <- WebProxy("127.0.0.1", 444) :> IWebProxy
同样重要的是:F#中的赋值语法为<-
,而不是C#中的=
。如果您使用=
,则会收到如下错误消息:
Type constraint mismatch. The type
bool
is not compatible with type
IWebProxy
The type 'bool' is not compatible with the type 'IWebProxy'