gpt4 book ai didi

haskell - 用仆人/围服务静态文件

转载 作者:行者123 更新时间:2023-12-04 11:36:31 24 4
gpt4 key购买 nike

我正在关注本教程 http://www.parsonsmatt.org/programming/2015/06/07/servant-persistent.html通过servant创建API。我想自定义服务器以提供静态文件,但找不到方法。
我正在使用 stack构建工具。
我修改了Main.hs文件的运行包含 static ( run port $ static $ logger $ app cfg ) 我导入了 Network.Wai.Middleware.Static (static) .我还添加了 wai-middleware-static >=0.7.0 && < 0.71到我的 cabal 文件。
当我运行 stack build我得到:( 更新:这部分完全是我的错误。 我将包添加到错误的 cabal 文件中.. 蹩脚。导入 Network.Wai.Middleware.Static 工作并提供静态文件。留下错误下面,以防有人搜索它并发现它有用。)

Could not find module ‘Network.Wai.Middleware.Static’
Perhaps you meant
Network.Wai.Middleware.Gzip (from wai-extra-3.0.7.1@waiex_GpotceEdscHD6hq9p0wPOJ)
Network.Wai.Middleware.Jsonp (from wai-extra-3.0.7.1@waiex_GpotceEdscHD6hq9p0wPOJ)
Network.Wai.Middleware.Local (from wai-extra-3.0.7.1@waiex_GpotceEdscHD6hq9p0wPOJ)
接下来我尝试使用servant的 serveDirectory如下(简化):
type  API = "users" :> Get   '[JSON]   [Person]
:<|> "static" :> Raw
server = createPerson :<|> serveDirectory "/static"
我收到此错误:
Couldn't match type ‘IO’ with ‘EitherT ServantErr IO’
arising from a functional dependency between:
constraint ‘Servant.Server.Internal.Enter.Enter
(IO Network.Wai.Internal.ResponseReceived)
(AppM :~> EitherT ServantErr IO)
(IO Network.Wai.Internal.ResponseReceived)’
arising from a use of ‘enter’
instance ‘Servant.Server.Internal.Enter.Enter
(m a) (m :~> n) (n a)’
at <no location info>
In the expression: enter (readerToEither cfg) server
In an equation for ‘readerServer’:
readerServer cfg = enter (readerToEither cfg) server
我是 Haskell 初学者,我对 Wai 不熟悉,所以甚至不确定从哪里开始。我需要对博客文章中的示例代码进行哪些更改才能提供静态文件?
编辑 :由于评论从默认 View 中隐藏,我将我的最后一条评论粘贴在这里:
这是马特的 code 的低调版本从他的博客。我将他的所有模块合并到一个文件中,删除了所有数据库内容,但没有清理扩展/导入。当我运行此代码时,我收到上述类型不匹配错误。请注意,此代码不使用 Network.Wai.Middleware.Static,而我使用的是符合条件的 Servant StaticFiles 导入。

最佳答案

如所述in the relevant section of servant's tutorial , 全程处理enter是让您的请求处理程序使用一些 monad m (在你的情况下是一些 ReaderT monad)并提供一种方法来转换 m 中的计算以仆人标准计算EitherT ServantErr IO单子(monad)。

但这里的问题是您在 ReaderT 中定义了一堆请求处理程序。 一个额外的服务静态文件,并调用enter所有这些。 ReaderT处理程序转换为 EitherT ...处理程序很好,但是 enter尝试转换 serveDirectory来自 ReaderT ... 的电话至EitherT ... .这当然不会很快发生,因为 serveDirectory不是 ReaderT ... 中的计算开始吧!

仆人可能会离开serveDirectory单独 - 在这一点上,对于我们是否应该这样做,或者是否最好将文件服务处理程序单独粘合到调用 enter 的结果,我没有明确的意见。在所有其他端点上。这是它的样子(查找 -- NEW 以查看更改):

type PersonAPI = 
"users" :> Capture "name" String :> Get '[JSON] Person
-- NEW: removed Raw from here

-- NEW
type WholeAPI = PersonAPI :<|> Raw

type AppM = ReaderT Config (EitherT ServantErr IO)

userAPI :: Proxy PersonAPI
userAPI = Proxy

-- NEW
wholeAPI :: Proxy WholeAPI
wholeAPI = Proxy

-- NEW: changed 'userAPI' to 'wholeAPI'
app :: Config -> Application
app cfg = serve wholeAPI (readerServer cfg)

readerServer :: Config -> Server WholeAPI
readerServer cfg = enter (readerToEither cfg) server
:<|> S.serveDirectory "/static" -- NEW

readerToEither :: Config -> AppM :~> EitherT ServantErr IO
readerToEither cfg = Nat $ \x -> runReaderT x cfg

server :: ServerT PersonAPI AppM
server = singlePerson

singlePerson :: String -> AppM Person
singlePerson str = do
let person = Person { name = "Joe", email = "joe@example.com" }
return person

无论如何,我已经将这个话题引起了其他仆人开发者的注意,谢谢!我们并没有真正考虑到 enter 之间的交互。和 serveDirectory到目前为止(好吧,我没有)。

关于haskell - 用仆人/围服务静态文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31020207/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com