如何为Haskell应用程序特定绑定端口?

Hah*_*pro -2 haskell heroku haskell-stack

当我运行并使用堆栈的应用程序时,它说

$ stack exec duckling-example-exe
no port specified, defaulting to port 8000
Listening on http://0.0.0.0:8000
Run Code Online (Sandbox Code Playgroud)

但是,我想将端口绑定到$ PORT(以便在heroku上托管)。

我应该怎么做?对新手问题很抱歉,但是我对Haskell还是一无所知,到目前为止还找不到任何解决方案。

eps*_*lbe 5

如果您不能这样做stack exec -- duckling-example-exe --port $PORT,则必须改编中的源代码exe/ExampleMain.hs

import System.Environment (lookupEnv)
...

main :: IO ()
main = do
  setupLogs
  tzs <- loadTimeZoneSeries "/usr/share/zoneinfo/"
  p <- lookupEnv "PORT"
  conf <- commandLineConfig $ maybe defaultConfig (`setPort` defaultConfig)
                                                  (p >>= readMaybe)
  httpServe conf $
    ifTop (writeBS "quack!") <|>
    route
      [ ("targets", method GET targetsHandler)
      , ("parse", method POST $ parseHandler tzs)
      ]
Run Code Online (Sandbox Code Playgroud)

这种变化是不是太困难的,因为你可以在阅读源代码如何quickHttpServe实现,增加端口是因为有点麻烦setPort :: Int -> Config m a -> Config m a,而不是采取Maybe Int这将有更方便的在这里。

由于lookupEnv返回a,Maybe String我们可以使用monadic绑定>>=readMaybe产生一个Maybe Int

该函数现在的工作方式如下:

  • 如果未PORT设置环境变量且未提供命令行参数,则选择默认值
  • 如果存在,则--port 8080覆盖PORT=9000