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.
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