F#Suave warbler功能

Sim*_*max 14 f# suave

我开始学习F#而且Suave我正在阅读F#Applied这本书.

我正在努力的一件事是warbler功能.我知道它与推迟执行有关,但我真的不明白为什么以及什么时候需要它.

显然我们也可以使用该request功能作为替代warbler.

任何人都可以提供有关使用这些功能的原因和时间的更多细节.

Hon*_*tan 24

另一个答案已经解释了warbler函数及其contextrequest函数的关系.我想说明你什么时候想要使用它们.

当您启动Suave服务器时,您需要为其提供请求处理管道WebParts- 路由,HTTP方法和响应生成功能.这意味着,当您启动Web服务器时,所有WebPart功能都已执行.

想象一下,打印当前服务器时间的简约Web应用程序:

let app = GET >=> path "/" >=> OK (string DateTime.Now)
Run Code Online (Sandbox Code Playgroud)

如果使用此app管道启动Web服务器app,则无论何时进行Web请求检索,您始终都会看到在创建值时生成的相同时间戳.

warbler函数及其专门版本,contextrequest不仅推迟执行,但也使网络服务器每次需要其结果时调用所提供的功能.

在示例场景中,这app将提供预期的结果:

let app = GET >=> path "/" >=> warbler (fun ctx -> OK (string DateTime.Now))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“所有 WebPart 函数都已执行”并不完全正确。在这种情况下,只需参数“OK”即可。在收到请求之前它不会真正执行。可以用 lambda 替换 `warbler`,但这需要您传递上下文:`(fun ctx -> OK (string DateTime.Now) ctx)`如图所示,它可以直接从它的定义中导出(fa -> faa) (2认同)

scr*_*wtp 18

这三个函数在某种意义上是相关的,request并且context是特殊版本的warbler.他们都做同样的事情 - 他们检查(在某些方面)他们的论点并给你一个函数来应用于那个论点.

请记住,Suave的基本"构建块" WebPart是一个功能HttpContext -> Async<HttpContext> option而不是一些具体的对象.这实际意味着这三个函数允许您检查这个HttpContext并基于组合WebPart使用.

其核心是什么warbler,非常简单:

let warbler f a = f a a  
// ('t -> 't -> 'u) -> 't -> 'u
Run Code Online (Sandbox Code Playgroud)

你给它一个函数f和参数a.函数f查看a并返回一个新函数't -> 'u,然后应用于该函数a.

关于warbler它是完全通用的 - 你可以在你使用的任何地方使用它,context或者request只要类型对齐,但​​它对Suave感兴趣的领域一无所知.

这就是为什么有"说域语言"的专业版本:

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 
Run Code Online (Sandbox Code Playgroud)

请注意,它们与warbler具有相同的"形状" - 唯一的区别是HttpContext类型是"硬编码" - 使其更方便使用.