let!在计算表达式中



我目前正在做很棒的fsharpforfunandprofit网站的计算表达式系列,我对计算系列的第4课"wrapped type"有一个问题。我试着再读一点,但是有一个重要的概念我没有领会。

实际上,我确实理解bind的定义:

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

,但有一件事我不明白,在这一点上是魔术时使用它的计算表达式与let!:

例如:

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"给我返回M<'T>,但是custId已经是未包装的'T,我看不到这个魔术是如何工作的…

是隐藏在let中的代码的一部分吗?Fsharp核心组件内的指令?谁能给我解释一下这是怎么回事?把T从包装纸里拿出来?

谢谢你的解释

this:

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

变成类似的东西(将monad类型命名为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)))))))

基本上每个let!对应一个Bind(通常可以忽略Delay)

正如你所看到的,计算表达式语法比嵌套的Binds要好得多——大多数支持某种一元表达式的语言都有类似的语法糖——甚至c# (from ... in ... select又名LINQ)

相关内容

  • 没有找到相关文章

最新更新