我在Haskell Servant App中具有类型级别功能(又称类型族),该应用程序接受一个Symbol并产生一个Type(路由),即
type family AppRoute (x :: Symbol) where
AppRoute x = x :> Get '[HTML] RawHtml
这有望在API中使用:
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute "about"
:<|> AppRoute "contact"
:<|> AppRoute "services"
:<|> AppRoute "blog"
:<|> AppRoute "products"
相应的服务器功能是
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
:<|> html
:<|> html
:<|> html
:<|> html
基本上,所有AppRoute都到达相同的端点(原始html文件)。有没有办法通过编写类似(不会编译)的东西来消除重复(参考最后五个路由)
type family AppRoute where
AppRoute = String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute _ -- * the problem is here. One function is needed here
使用相应的服务器
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
实际上,AppRoutes是一个类型级别的函数,它接受任何字符串并返回路由。
总之,而不是写作
:<|> AppRoute "about" :<|> AppRoute "contact" :<|> AppRoute "services" :<|> AppRoute "products"
我只想写 :<|> AppRoute _
答案 0 :(得分:1)
您可以使用Capture
捕获任何路径。但是,必须在其前加上:
char。例如
type AppRoute = Capture "routePath" String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute
现在,AppRoute
将在yourserver.com/:thisIsMyPath/
上触发,并将"thisIsMyPath"
作为端点的参数传递。我目前不知道如何绕过此:
。假设html
是目前不依赖于给定路径的端点,则可以将整个服务器定义为
server :: Server ServerAPI
server = html
:<|> userServer
:<|> adminServer
:<|> const html
您可能会读到here。
顺便说一句,为什么不使用type
别名而不是tank类型的族?通常在我的Servant应用中
type AppRoute (x :: Symbol) = x :> Get '[HTML] RawHtml
哪个效果很好。
答案 1 :(得分:0)
如果有人仍在寻找应答者,则还有另一种捕获任何路线的方法。看看CaptureAll类型