1

我正在玩这个不错的教程中的一个简单的 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    
4

3 回答 3

4

As others already explained, the problem is that = is the comparison operator. In this case, you need an assignment, which is <-.

However, F# actually performs upcasts implicitly in a couple of cases and assignment is one of them, so you do not need to add :> IWebProxy to cast the object. The following will work just fine:

req.Proxy <- new WebProxy("127.0.0.1", 444)

Aside from assignment, F# also does implicit upcasting when passing arguments to methods or functions. It does not do this for the comparison operator (because you want to know, without any ambiguities, what types are compared.)

于 2013-08-17T14:49:16.797 回答
1

好吧,这里至少有两件事是您意想不到的:

  • req.Proxy = new WebProxy(...)是一个比较,你可能想要req.Proxy <- new WebProxy(...)代替。
  • F# 不进行自动向上转换。因此,您可能需要使用类似req.Proxy <- new WebProxy(...) :> _. 这告诉 F#“向上转换到适合这里的任何东西”。

(我实际上并没有运行你的代码,所以你可能会遇到更多问题,但这两个对于 C# 程序员来说肯定很重要。)

于 2013-08-17T13:00:49.587 回答
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'
于 2013-08-17T13:00:54.043 回答