让的机制!在计算表达式中
the mechanics of let! in computation expressions
我目前正在研究神话般的 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 已经是 unwrapped 'T 并且我在任何地方都看不到这个魔术是如何工作的...
是不是有部分代码隐藏在let! Fsharp 核心组件中的指令?谁能给我解释一下怎么让!从包装纸中取出 T'?
感谢您的解释
这个:
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)
我目前正在研究神话般的 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 已经是 unwrapped 'T 并且我在任何地方都看不到这个魔术是如何工作的...
是不是有部分代码隐藏在let! Fsharp 核心组件中的指令?谁能给我解释一下怎么让!从包装纸中取出 T'?
感谢您的解释
这个:
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)