F # Функция сувольной камышевки

Я начал изучать F # и Suave, и я читаю книгу F # Applied.

Одна вещь, с которой я борюсь, - это функция warbler. Я знаю, что это связано с отсрочкой исполнения, но я не понимаю, почему и когда это необходимо.

По-видимому, мы могли бы использовать функцию request в качестве альтернативы warbler.

Может ли кто-нибудь предоставить более подробную информацию о том, почему и когда эти функции используются.

Ответ 1

Эти три функции связаны в том смысле, что request и context являются специализированными версиями warbler. Они все делают то же самое - они проверяют (некоторые аспекты) свои аргументы и возвращают вам функцию, чтобы применить к этому аргументу.

Помните, что основной "строительный блок" Suave, WebPart, является функцией HttpContext -> Async<HttpContext> option, а не конкретным объектом. Это эффективно означает, что эти три функции позволяют вам проверять этот HttpContext и основываться на компиляции WebPart.

В своей основе, что warbler делает очень просто:

let warbler f a = f a a  
// ('t -> 't -> 'u) -> 't -> 'u

Вы даете ему функцию f и аргумент a. Функция f смотрит на a и возвращает вам новую функцию 't -> 'u, которая затем применяется к a.

Дело в warbler заключается в том, что он полностью общий - вы можете использовать его в любом месте, где бы вы использовали context или request, пока типы выравниваются, но он ничего не знает о домене. Suave is заинтересованный.

Вот почему есть специализированные версии, которые "говорят на языке домена":

let request apply (a : HttpContext) = apply a.request a
// (HttpRequest -> HttpContext -> 'a) -> HttpContext -> 'a 
let context apply (a : HttpContext) = apply a a
// (HttpContext -> HttpContext -> 'a) -> HttpContext -> 'a 

Обратите внимание, что они имеют ту же самую "форму", что и warbler, - единственное отличие состоит в том, что тип HttpContext "жестко закодирован", что делает его более удобным для использования.

Ответ 2

Другой ответ уже объяснил функцию warbler и ее отношение к функциям context и request. Я хотел бы показать, когда вы хотите использовать их.

Когда вы запускаете сервер Suave, вам необходимо предоставить его конвейер обработки запросов WebParts - маршрутизацию, методы HTTP и функции генерации ответа. Это означает, что к моменту запуска веб-сервера все функции WebPart уже выполнены.

Представьте минималистичное веб-приложение, которое печатает текущее время сервера:

let app = GET >=> path "/" >=> OK (string DateTime.Now)

Если вы запустите веб-сервер, используя этот конвейер app, вы всегда увидите ту же временную метку, которая была создана при создании значения app, независимо от того, когда вы делаете веб-запросы, извлекая их.

Функция warbler и ее специализированные версии context и request не только откладывают выполнение, но также позволяют веб-серверу вызывать предоставленную функцию каждый раз, когда ей нужен ее результат.

В примере сценария это app обеспечит ожидаемые результаты:

let app = GET >=> path "/" >=> warbler (fun ctx -> OK (string DateTime.Now))