2015-05-16 39 views
0

是否可以在編譯時通過使用Template Haskell或其他方式通過配置文件動態添加路由。在編譯時在Scotty動態添加路由

Scotty有一個功能addRoute但我想動態地使用它。

import qualified Data.Text.Lazy as LTB 

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

欲迭代sampleRoutes陣列上方和在編譯時定義路由和響應。

import Web.Scotty 

main = scotty 3000 $ do 
    middleware logStdoutDev 
    someFunc sampleRoutes 
+0

不使用TH我已經能夠做'do {middleware logStdoutDev; ((get(「/ hello」))(text(LTB.pack(「hello」)))); ((get(「/ world」))(text(LTB.pack(「world」))))}'我如何在基於某個列表的'ScottyM()'monad內部動態編寫動作? – user2512324

+0

小*提示*:如果您只是使用'{ - #LANGUAGE OverloadedStrings# - }'(和'Text',而不是'String'可能是一個'*'),那麼您可以在那裏刪除(大部分,如果不是全部)'LTB.pack'如果你不真的需要'String = [Char]'部分),我也不會這麼做。 – Carsten

回答

2

OK,所以給出了上述列表中,我假設你正在尋找的東西,相當於手寫如下:

{-! 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()值的常規函數​​。如果我有

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

然後在前main功能是完全等同於

main = do 
    middleware logStdoutDev 
    r1 
    r2 

此,和r1r2共同結構提出了以下解決方案:

import Control.Monad (forM_) 

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

我沒有提及'forM_'。非常感謝。太糟糕了,我不能使用TH。我正在尋找一個學習它的機會。 – user2512324

+0

當你*不需要使用TH時總是一件好事... – Cactus