【问题标题】:the mechanics of let! in computation expressions让机制!在计算表达式中
【发布时间】:2015-05-19 09:21:03
【问题描述】:

我目前正在研究 fsharpforfunandprofit 网站的计算表达式系列,我对计算系列的第 4 课“包装类型”有疑问。我尝试进一步阅读,但有一个重要的概念我没有掌握。

其实我明白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 ,但 custId 已经是 未包装的 'T strong> 而且我在任何地方都看不到这个魔术是如何工作的......

它是隐藏在let中的代码的一部分吗! Fsharp 核心程序集中的指令?有人可以向我解释一下如何让!从包装中取出 T'?

感谢您的解释

【问题讨论】:

  • 这正是Bind 的用途(展开):您可以将let! custId = ... 视为Bind (getCustomerId "Alice") (fun custId -&gt; ... the next line(s)),所以每个let! 都会让您获得另一个级别的Bind跨度>
  • let! 本身就是 syntactic-sugar 可以 desugars 绑定 - 你可以在这个post from Don 找到一些细节
  • 好的,明白了!非常感谢...
  • 要我把它包装成答案吗? ...一瞬间

标签: f# computation-expression


【解决方案1】:

这个:

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

desugar 变成类似(将 monad 类型命名为 DB&lt;'t&gt;):

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)

【讨论】:

  • 我忘记了绑定方法 bind(m,f) 实际上在做什么。当匹配 m 时,它将 f 应用于 a,从而解开该值以供将来使用。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
相关资源
最近更新 更多