2013-08-17 32 views
1

我正在玩一个简单的f#示例this nice tutorial。并遇到这个非常奇怪的错误。在向webrequest添加代理后,它告诉我类型WebProxy与预期类型IWebProxy不兼容。这有点奇怪,为什么我的C#锤子在F#中没有工作?这个表达式预计有IWebProxy类型,但这里有类型WebProxy

我在这里做错了什么?

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  

回答

3

正如其他人已经解释过,问题是=是比较操作。在这种情况下,您需要一个作业,即<-

但是,在几种情况下,F#实际上会隐式执行upcasts,而赋值就是其中之一,因此您不需要添加:> IWebProxy来投射对象。以下将工作得很好:

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

除了赋值,F#还向方法或函数传递参数时隐式上传。它不会为比较运算符做这件事(因为您想知道,没有任何含糊之处,哪些类型被比较。)

1

嗯,至少有两件事情,你不要指望在这里:

  • req.Proxy = new WebProxy(...)是一个比较,你可能想req.Proxy <- new WebProxy(...)代替。
  • F#不会自动上传。因此,您可能需要执行类似req.Proxy <- new WebProxy(...) :> _的静态上传。这告诉F#“上传到任何适合的地方”。

(我没有实际运行你的代码,所以你可能有更多的问题,但是这两个肯定是一个C#程序员很重要的。)

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' 
相关问题