在最后一个链接的Option.bind中得到一个中间值?

ca9*_*3d9 0 f#

我有以下代码

let getHtml location = 
    let request (url:string) = 
        let response = httpRequest (getFullUri url)
        response.Headers.TryFind "Location"

    request location  
    |> Option.bind (fun x -> request x) 
    |> Option.bind (fun x -> request x) // need the return of httpRequest inside request
Run Code Online (Sandbox Code Playgroud)

我希望代码返回最后一次调用httpRequest.不是回归request.


更新:尝试以下代码.最后一个错误snd.我想我可以使用一个可变变量来实现它.但它是F#惯用语吗?

let getHtml location = 
    let request (url:string) = 
        let response = httpRequest (getFullUri url)
        match response.Headers.TryFind "Location" with 
        | Some location -> Some location, response
        | None -> None, response

    request location |> fst
    |> Option.bind (fun x -> request x |> fst) 
    |> Option.bind (fun x -> request x |> snd) // Error on snd
Run Code Online (Sandbox Code Playgroud)

使用可变变量?

let getHtml location = 
    let mutable resp : FSharp.Data.HttpResponse = ???
    let request (url:string) = 
        let response = httpRequest (getFullUri url)
        resp <- response
        response.Headers.TryFind "Location"

    request location 
    |> Option.bind (fun x -> request x) 
    |> Option.bind (fun x -> request x)

    if not (resp = null) then Some resp else None
Run Code Online (Sandbox Code Playgroud)

Aar*_*ach 5

我认为你想要做的其实就是做getHtml递归,这样当HTTP请求返回201或300级响应代码时,你会按照Location标题进入重定向页面并返回正确的HTML.您可以使用response.StatusCode和位置标题上的简单模式匹配来执行此操作,如下所示:

open FSharp.Data

// stub
let getFullUri (url: string) = 
    sprintf "%A" <| System.UriBuilder(url)

// stub
let httpRequest = Http.Request

// fetches the requested URL, following redirects as necessary
let rec getHtml location = 
    let response = httpRequest (getFullUri location)
    match response.StatusCode, response.Headers |> Map.tryFind "Location" with
    | (status, Some redirectUrl) when status = 201 || (status >= 300 && status < 400) -> 
        getHtml redirectUrl
    | _ -> 
        response
Run Code Online (Sandbox Code Playgroud)

这就是你想要的吗?我使用以下返回302的URL对其进行了测试,并获得了重定向页面的HTML:https: //jigsaw.w3.org/HTTP/300/302.html