我刚开始阅读Tamizhvendan S的书 f# Applied,看到了下面的代码片段:
type WebPart = Context -> Async<Context option>
我一直在浏览微软的f#文档以及我最喜欢的f#网站,Scott Wlaschin的F# for Fun and Profit
,但无法找到任何关于这种类型的参考。看起来不像是记录机。它看起来就像一个普通的旧函数。那么它是什么呢?
谢谢大家的帮助。
您正在查看的WebPart
类型来自Suave。您可以在https://suave.io/async.html上阅读更多信息,但我将进行总结。你是正确的:它是一个函数的类型。具体来说,它是一个接受Context
(在Suave中是HTTP请求记录和响应记录的组合)并异步返回Context option
的函数。也就是说,由于某些请求可能会失败,该函数可以选择返回None
而不是返回一个值。由于一些请求可能需要很长时间,因此所有请求都被视为异步返回,因此Async
.
为了将两个请求链接在一起,Suave提供了绑定操作符>=>
,这样您就不必一直输入async { match result1 with None -> None | Some x -> return! request2 x
的样板;相反,您可以输入request1 >=> request2
来获得相同的效果。
如果您需要更多的帮助,并且通过阅读Suave文档还没有提供您需要的帮助,请告诉我们,我们将尝试进一步解释
这段注释太长了。我从来没用过Suave。然而,我认为我可以从所涉及的类型的一元属性中猜测出>=>
不是绑定操作符,而是Kleisli组合操作符。在不遵守单子定律或试图理解范畴理论的情况下,只要假设签名是:
val ( >>= ) : Async<'a option> -> ('a -> Async<'b option>) -> Async<'b option> val ( >=> ) : ('a -> Async<'b option>) -> ('b -> Async<'c option>) -> 'a -> Async<'c option>
绑定操作符接受Async<'a option>
,并通过绑定函数'a -> Async<'b option>
将其转换为Async<'b option>
。Kleisli操作符将两个绑定函数组合为第三个绑定函数。
这些操作符作用于一元类型和函数,它们比由类型缩写(如type WebPart = Context -> Async<Context option>
)描述的具体类型更泛型。操作符的实现几乎是自然的。
let (>>=) request1 binder = async {
let! result1 = request1
match result1 with
| None -> return None
| Some x -> return! binder x }
let (>=>) f g a = f a >>= g