关于haskell:在Scotty编译时动态添加路由

Dynamically add routes at compile time in Scotty

是否可以在编译时通过配置文件使用 Template Haskell 或任何其他方式动态添加路由。

Scotty 有一个函数 addRoute 但我想动态使用它。

例子

1
2
3
4
import qualified Data.Text.Lazy as LTB

sampleRoutes :: [(String, LTB.Text)]
sampleRoutes = [("hello", LTB.pack"hello"), ("world", LTB.pack"world")]

我想遍历 sampleRoutes 数组并在编译时定义路由和响应。

1
2
3
4
5
import Web.Scotty

main = scotty 3000 $ do
  middleware logStdoutDev
  someFunc sampleRoutes


好的,鉴于上面的列表,我假设您正在寻找相当于手写以下内容的内容:

1
2
3
4
5
6
7
8
{-! LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Data.String

main = scotty 3000 $ do
  middleware logStdoutDev
  get (fromString $ '/' :"hello") (text"hello")
  get (fromString $ '/' :"world") (text"world")

好消息是,那里没有任何东西需要任何 TH 魔法!

请记住,addroute / get 只是返回 ScottyM () 值的常规函数??。如果我有

1
2
r1 = get (fromString $ '/' :"hello") (text"hello")
r2 = get (fromString $ '/' :"world") (text"world")

那么前面的 main 函数完全等价于

1
2
3
4
main = do
  middleware logStdoutDev
  r1
  r2

这和 r1r2 的共同结构建议以下解决方案:

1
2
3
4
5
6
import Control.Monad (forM_)

main = do
  middleware logStdoutDev
  forM_ sampleRoutes $ \\(name, response) ->
    get (fromString $ '/':name) (text response)