How to extract function (specificali hyper handle function)

I’m playing with example from hyper http framework

module Examples.HelloHyper where

import Prelude
import Control.Monad.Indexed.Qualified as Ix
import Effect (Effect)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer)
import Hyper.Response (closeHeaders, respond, writeStatus)
import Hyper.Status (statusOK)

main :: Effect Unit
main =
  let app = Ix.do
        writeStatus statusOK
        closeHeaders
        respond "Hello, Hyper!"
  in runServer defaultOptionsWithLogging {} app

so as first example I decided that it would by better if app was named handler and extracted to sepparated function, but after quite time of experimenting and copy pasting I can’t figure out what type that function is supposed to be

module Main where

import Prelude

import Control.Monad.Indexed.Qualified as Ix
import Effect (Effect)
import Effect.Aff (Aff)

import Hyper.Middleware (Middleware)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer, HttpRequest, HttpResponse)
import Hyper.Response (closeHeaders, respond, writeStatus, StatusLineOpen, ResponseEnded)
import Hyper.Status (statusOK)
import Hyper.Conn (Conn)

-- ??
handler = Ix.do
  writeStatus statusOK
  closeHeaders
  respond "Hello, Hyper!"

main :: Effect Unit
main = runServer defaultOptionsWithLogging {} handler

Thank you in advance :slight_smile:

Unfortunately, the compiler can’t completely fill this one in for us. Here’s what ended-up working:

type ComponentsType = Record ()

components :: ComponentsType
components = {}

handler :: Middleware Aff (Conn HttpRequest (HttpResponse StatusLineOpen) ComponentsType) (Conn HttpRequest (HttpResponse ResponseEnded) ComponentsType) Unit
handler = Ix.do
  writeStatus statusOK
  closeHeaders
  respond "Hello, Hyper!"

main :: Effect Unit
main = runServer defaultOptionsWithLogging components handler

https://try.ps.ai/?gist=2f26768a68eebdaa3e68db7d650c14ec

I started by copying the function signature from runServer:

Middleware Aff (Conn HttpRequest (HttpResponse StatusLineOpen) c) (Conn HttpRequest (HttpResponse ResponseEnded) c') Unit

But then had to fill-in the missing c and c' types. We know what c is from the empty record passed {}. Then I just made a guess and tried the same for c' - Not sure if that’s the most ideal. An intermediate components :: ComponentsType should help with maintainability.

Edit: You can also make the signature a bit less busy with something like:

type ConnHttp resp = Conn HttpRequest (HttpResponse resp) ComponentsType

handler :: Middleware Aff (ConnHttp StatusLineOpen) (ConnHttp ResponseEnded) Unit

https://try.ps.ai/?gist=6f52e4ab2a7982765c9812b2dc490b40

2 Likes

Thank you, now it seems so obvious :smile: