Механика дай! в выражениях вычислений

В настоящее время я работаю над серией выражений для вычислений на потрясающем веб-сайте fsharpforfunandprofit, и у меня возник вопрос относительно урока 4 "Обернутый тип" серии вычислений. Я попытался прочитать немного дальше, но есть важное понятие, которое я не понимаю.

На самом деле, я понимаю определение связывания:

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 "Алиса" возвращает мне M<'T>, но custId - это уже развернутый' T, и я нигде не вижу, как работает этот фокус...

Является ли это частью кода, скрытого в let! Инструкция в сборке ядра Fsharp? Может ли кто-нибудь объяснить мне, как пусть! достать Т 'из своей обертки?

Спасибо за ваши объяснения

1 ответ

Решение

Этот:

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

будет desugar к чему-то вроде (назвав тип монады просто 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)))))))

так что в основном вы получаете Bind уровень для каждого let! (обычно вы можете игнорировать Delay)

Как вы можете видеть, синтаксис вычислительных выражений намного лучше, чем вложенный Binds - большинство языков, которые поддерживают монадические выражения некоторого вида, имеют похожий синтаксический сахар - даже C# (from ... in ... select он же LINQ)

Другие вопросы по тегам