WAI中的ResponseReceived数据类型

时间:2018-10-23 16:55:02

标签: haskell

我想知道为什么WAI的Aplication类型被设计为Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived。为什么不Request -> (Response -> IO ()) -> IO ()呢?文档说

  

一种特殊的数据类型,指示WAI处理程序已收到响应。这是为了避免在Application的定义中需要Rank2Types。

     

强烈建议只有WAI处理程序才能导入和使用此数据类型的数据构造函数。

这种特殊的数据类型如何帮助避免Rank2Types

1 个答案:

答案 0 :(得分:6)

Application应该是

type Application = Request -> (forall b. (Response -> IO b) -> IO b)
-- a.k.a. Request -> Codensity IO Response
-- newtype Codensity f a = Codensity { runCodensity :: forall b. (a -> f b) -> f b }
-- which is closely related to continuations

也就是说,Application使用Request,函数f,并用f调用Response

app :: Application
app req f = f _resp

Application 强制您致电f。除了IO b之外,没有其他函数可以在app内产生f,因此,由于app必须产生IO bapp必须致电fwai依赖于app调用f,它可以通过此Application来强制实施。但是,Application的排名较高,这在某种程度上是不可取的。

实际使用的解决方案是:

type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
-- a.k.a. Request -> ContT ResponseReceived IO Response
-- in general, ContT is "bigger" and "weaker" than Codensity
-- but, in exchange, does not require higher ranked types

app :: Application
app req f = f _resp

f仍然是app手上唯一可以产生ResponseReceived的东西,只要app不违反与{{ 1}},然后导入构造函数。您不能将wai替换为ResponseReceived。每个人及其母亲都可以使用()的构造函数(())。我认为甚至不可能。这使其不适用于()

Application