Let the mechanics! in calculation expressions

I am currently working on a computation series for an exploit from the fabulous fsharpforfunandprofit website, and I have a question regarding lesson 4 "wrapped type" computation series. I've tried reading a little further, but there is an important concept that I don't understand.

Actually, I understand the definition of bind:

member Bind : M<'T> * ('T -> M<'U>) -> M<'U>

      

but one thing I don't understand at the moment is the magic when using it in a computation expression with let !:

For example, in:

let product'' = 
    dbresult {
        let! custId = getCustomerId "Alice"
        let! orderId = getLastOrderForCustomer "" // error!
        let! productId = getLastProductForOrder orderId 
        printfn "Product is %s" productId
        return productId
        }
printfn "%A" product''

      

getCustomerId "Alice" returns M <T> , but custId is already unrolled and I don't see anywhere how this magic trick works ...

Is this part of the code hidden in let! instructions in Fsharp core? Can someone explain to me how they let me in! get T 'out of its wrapper?

Thanks for your explanations.

+3


source to share


1 answer


let product'' = 
    dbresult {
        let! custId = getCustomerId "Alice"
        let! orderId = getLastOrderForCustomer "" // error!
        let! productId = getLastProductForOrder orderId 
        printfn "Product is %s" productId
        return productId
        }

      

would desugar for something like (calling the monad type as simple DB<'t>

):



let product'' = 
   DB.Delay(fun () ->
       DB.Bind(getCustomerId "Alice",(fun custId ->
          DB.Bind(getLastOrderForCustomer "",(fun orderId ->
             DB.Bind(getLastProductForOrder orderId, (fun productId ->
                printfn "Product is %s" productId
                DB.Return productId)))))))

      

so basically you get a level Bind

for each let!

(usually you can ignore Delay

)

As you can see, the computational expression syntax is much better than nested Binds

- most languages ​​that support monadic expressions of some kind have similar syntactic sugar - even C # ( from ... in ... select

aka LINQ)

+6


source







All Articles