Embed workflow/monad in another workflow/monad?

138 Views Asked by At

For example, I have a workflow for logging, and I want to use async in the logging workflow. How to call logging's bind in async workflow?

log {
    async {
       let! a = .... // Need to do logging here.
       let! b = .... // Need to do async here

Edit: I heard that it's a good idea to use workflow to replace AOP for cross cutting concerns purpose in F#. I'm not sure how to handle the embedding issues. Or it's not a good idea to use workflow for it?

2

There are 2 best solutions below

1
On

F# does not have any automated way of doing this. What you essentially want is to create a composed computation that captures two different behaviors. The best way to do this is to define a new computation, say asyncLog, that lets you do both of the things you need. This is not easy, but the following are good starting points:

In reality, you do not need to do this that often in F#, because there are not that many computation expressions to compose.

In your example, you're using async and log. Although logging makes for a great demo when explaining how computation expressions work, I'm not sure that I would use computation expressions to add logging to my application in practice - it seems easier to just use a global logger object and call it directly (but it really depends on what your log computation does behind the covers).

0
On

You can use AsyncReader computation expression for this https://github.com/jack-pappas/ExtCore/blob/master/ExtCore/Control.fs#L1769 and lift Asyncs and Readers if you need.