开发者

F# - The type was expected to have type Async<'a> but has string -> Asnyc<'a> instead

After shamelessly pilfering a code snippet from Tomas Petricek's Blog: http://tomasp.net/blog/csharp-fsharp-async-intro.aspx Specifically, this one (and making a few alterations to it):

     let downloadPage(url:string) (postData:string) = async {
  let request = HttpWebRequest.Create(url)
// Asynchronously get response and dispose it when we're done
  use! response = request.AsyncGetResponse()
  use stream = response.GetResponseStream()
  let temp = new MemoryStream()
  let buffer = Array.zeroCreate 4096 

   // Loop that downloads page into a buffer (could use 'while' 
   // but recursion is more typical for functional language)
  let rec download() = async { 
   let! count = stream.AsyncRead(buffer, 0, buffer.Length)
   do! temp.AsyncWrite(buffer, 0, count)
   if count > 0 then return! download() }

   // Start the download asynchronously and handle results
  do! download()
  temp.Seek(0L, SeekOrigin.Begin) |> ignore
  let html = (new StreamReader(temp)).ReadToEnd()
  return html };;

I tried to do the following with it, and got the error on the last line:

The type was expected to have type Async<'a> but has string -> Asnyc<'a> instead

I googled the error but couldn't find anything that revealed my particular issue.

let postData = "userid=" + userId + "&password=" + password + "&source=" + sourceId + "&version=" + version
let url = postUrlBase + "100/LogIn?" + postData
Async.RunSynchronously (downloadPage(url, postData));;

Also, how would I modify the code so that it downloads a non-ending byte stream (but with occasional pauses between each burst of bytes) asynchronously instead of a string? How would I integrate reading this byte stream as it comes through? I realize this is more than one question, but since they are are all closely related I figured one question would save some time.

Thanks in advance,

Bob

P.S. As I am still new to F# please feel free to make any alterations/suggestions to my code which shows how开发者_运维技巧 its done in a more functional style. I'm really trying to get out of my C# mindset, so I appreciate any pointers anyone may wish to share.

Edit: I accidentally pasted in the wrong snippet I was using. I did make an alteration to Tomas' snippet and forgot about it.


When I attempt to run your code downloadPage(url, postData) doesn't work as downloadPage expects two seperate strings. downloadPage url postData is what is expected.

If you changed the let binding to tuple form, or let downloadPage(url:string, postData:string) your call would have worked as well.

To explain why you got the error you got is more complicated. Curried form creates a function that returns a function or string -> string -> Async<string> in your case. The compiler therefore saw you passing a single parameter (tuples are single items after all) and saw that the result would have to be a string -> Async<string> which is not compatible with Async<string>. Another error it could have found (and did in my case) is that string * string is not compatible with string. The exact error being Expected string but found 'a * 'b.


This is what I had:

Async.RunSynchronously (downloadPage(url, postData));;

this is what worked after continued random guessing:

Async.RunSynchronously (downloadPage url postData);;

Although, I'm not sure why this change fixed the problem. Thoughts?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜