【问题标题】:Navigating Haskell Servant API with Lucid WebUI使用 Lucid WebUI 导航 Haskell Servant API
【发布时间】:2019-11-23 19:22:32
【问题描述】:

我了解到我可以通过以下方式使用仆人和 Lucid 定义我的 API:

type ClientAPI = 
    "users" :> Get '[HTML] (Html ()) 
    :<|> "userdata" :> Get '[HTML] (Html ())

然后,如果我想在我的 HTML 中添加指向其中一个端点的链接,我可以使用 Lucid 提供的“a_”函数,例如

a_ [href_ "users"] "Show users"

这种方法的问题是我需要重复两次端点的名称。 “用户”出现在 API 定义和 a_ 标记中。结果,如果我在一个地方更改它,另一个地方会立即停止工作。

有没有办法定义一个可以在两个地方都使用的单一符号?比如:

data MySites = UserSite | UserDataSite -- potentially more

type ClientAPI' =
    UserSite :> Get '[HTML] (Html ())
    -- ......

let html =
...
   a_ [href_ UserSite] "Show users"
...

【问题讨论】:

标签: haskell routing servant haskell-lucid


【解决方案1】:

如果你只是想对字符串"user"进行抽象,你可以使用类型别名,然后使用GHC.TypeLits.symbolVal获取值级别的字符串:

{-# LANGUAGE DataKinds #-}

import Data.Proxy
import GHC.TypeLits

type UserSite = "user"

html = ... href_ (symbolVal (Proxy :: Proxy UserSite)) ...

您还可以通过使用 AllowAmbiguousTypes 定义一个助手来缩短 symbolVal 调用:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}

urlpath :: forall s . KnownSymbol s => String
urlpath = symbolVal (Proxy :: Proxy s)

html = ... href_ (urlpath @UserSite) ...

(我实际上以为它在某个地方的标准库中,但我找不到它。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多