-
Notifications
You must be signed in to change notification settings - Fork 27
Open
Description
The res
type in Conn
is implicitly Type -> Type
despite its declaration not showing that.
module Hyper.Conn where
-- | A `Conn` models the entirety of an HTTP connection, containing the fields
-- | `request`, `response`, and the extensibility point `components`.
type Conn req res components =
{ request :: req
, response :: res -- (res :: Type -> Type)
, components :: components
}
This isn't immediately clear to the end-reader (unless one reads through the source code or potentially the docs). Moreover, the lack of using a kind here also allows one to use other non-ResponseState types here (e.g. res Int
rather than res StatusLineOpen
).
I propose we instead define a kind and more clearly indicate that. When I worked on implementing this, I found that the code is easier if the Conn
type also has a type parameter for the responseState
that it applies to res
in its definition. In other words...
module Hyper.Conn where
-- | Defines the states of an HTTP request stream. It tracks whether or not
-- | some content has already been written to an HTTP request stream.
-- |
-- | Proper order of computations. Items marked with an asterisk indicate that
-- | transitioning back to the same state is valid:
-- | StatusLineOpen -> HeadersOpen* -> BodyOpen* -> ResponseEnded
foreign import kind ResponseState
-- | Type indicating that the status-line is ready to be
-- | sent.
foreign import data StatusLineOpen :: ResponseState
-- | Type indicating that headers are ready to be
-- | sent, i.e. the body streaming has not been started.
foreign import data HeadersOpen :: ResponseState
-- | Type indicating that headers have already been
-- | sent, and that the body is currently streaming.
foreign import data BodyOpen :: ResponseState
-- | Type indicating that headers have already been
-- | sent, and that the body stream, and thus the response,
-- | is finished.
foreign import data ResponseEnded :: ResponseState
-- | A `Conn` models the entirety of an HTTP connection, containing the fields
-- | `request`, `response`, and the extensibility point `components`.
type Conn request response components (responseState :: ResponseState) =
{ request :: request
, response :: response responseState
, components :: components
}
-- now the `ResponseTransition` type alias is defined like so:
-- | A middleware transitioning from one `Response` state to another.
type ResponseStateTransition m (res :: ResponseState -> Type) (from :: ResponseState) (to :: ResponseState) =
forall req comp.
Middleware
m
(Conn req res comp from)
(Conn req res comp to)
Unit
Metadata
Metadata
Assignees
Labels
No labels