ca9163d9
ca9163d9

Reputation: 29227

Implement do while in F#?

I tried the following code to implement do while in F#.

let listObjects bucketName = asyncSeq {
    use client = new AmazonS3Client(RegionEndpoint.USEast2)
    let request = new ListObjectsV2Request(BucketName = bucketName, MaxKeys = 10)

    while (
        let! response = client.ListObjectsV2Async(request) |> Async.AwaitTask
        for entry in response.S3Objects do
            yield entry.Key
        response.IsTruncated) do ()

However, it cannot compile? Is the following code the only option?

let listObjects bucketName = asyncSeq {
    use client = new AmazonS3Client(RegionEndpoint.USEast2)
    let request = new ListObjectsV2Request(BucketName = bucketName, MaxKeys = 10)
    let! response = client.ListObjectsV2Async(request) |> Async.AwaitTask
    for entry in response.S3Objects do // do while
        yield entry.Key
    while response.IsTruncated do
        let! response = client.ListObjectsV2Async(request) |> Async.AwaitTask
        for entry in response.S3Objects do
            yield entry.Key

Upvotes: 1

Views: 313

Answers (1)

Aaron M. Eshbach
Aaron M. Eshbach

Reputation: 6510

You can generally use tail-recursion in F# to solve the same sort of problems you'd solve with loops in C#. I'm not entirely clear on what your intended while-loop behavior is, but here's an example of tail-recursivlely yielding the S3Objects until response.IsTruncated is false:

let listObjects bucketName = 
    asyncSeq {
        use client = new AmazonS3Client(RegionEndpoint.USEast2)
        let request = new ListObjectsV2Request(BucketName = bucketName, MaxKeys = 10)
        let! response = client.ListObjectsV2Async(request) |> Async.AwaitTask
        let rec getKeys () = 
            asyncSeq {
                for entry in response.S3Objects do
                    yield entry.Key
                if response.IsTruncated
                then yield! getKeys ()
            }   

        yield! getKeys()            
    }

Upvotes: 4

Related Questions