Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a sequence of Task<MyType> to a sequence of MyType

So I currently have a sequence of type seq<System.Threading.Tasks.Task<Restaurant>> and I want to turn it into a sequence of type seq<Restaurant>.

I'm currently using TaskBuilder.fs library and from my research, I need to use either let! or do! for this situation but they require task {} which when used with Seq.map bring back the same Task type.

let joinWithReviews (r : Restaurant) =
    task {
        let! reviewResult = Reviews.Database.getByLocationId cnf.connectionString r.Restaurant_Id
        match reviewResult with
        | Ok reviewResult ->
            let restaurant = { r with Reviews = (List.ofSeq reviewResult)}
            return restaurant
        | Error ex ->
            return raise ex
    }

let indexAction (ctx : HttpContext) =
    task {
        let (cnf:Config) = Controller.getConfig ctx
        let! result = Restaurants.Database.getAll cnf.connectionString
        match result with
        | Ok result ->
            let restaurantWithReviews = (Seq.map joinWithReviews result)
            return index ctx (List.ofSeq restaurantWithReviews)
        | Error ex ->
            return raise ex
    }

So my result is of type Seq<Restaurant> and I need to add reviews to each restaurant so I use Seq.map to get restaurantWithReviews which is type seq<System.Threading.Tasks.Task<Restaurant>> which I won't be able to use.

like image 328
Danson Avatar asked Oct 19 '25 05:10

Danson


1 Answers

The .NET method System.Threading.Tasks.Task.WhenAll will convert seq<Task<'a>> to Task<'a[]>. You can get the result with let! if you're inside a task { } block.

let restaurants: seq<Restaurant>

let! withReviews: Restaurant[] =
    restaurants
    |> Seq.map joinWithReviews
    |> Task.WhenAll
like image 130
libertyernie Avatar answered Oct 22 '25 00:10

libertyernie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!