首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ReaderT转换Happstack的ServerPart响应?

如何使用ReaderT转换Happstack的ServerPart响应?
EN

Stack Overflow用户
提问于 2012-01-26 12:40:24
回答 1查看 276关注 0票数 2

这是我第一次玩Monad Transformers。这是一个简单的happstack应用程序。

代码语言:javascript
复制
{-# LANGUAGE OverloadedStrings #-}

import Happstack.Lite 
import qualified Data.ByteString.Lazy.Char8 as L

main :: IO ()
main = do
    serve Nothing hello 

hello :: ServerPart Response
hello = do
    ok $ toResponse ("Hello" :: L.ByteString)

我希望能够更改hello,这样它就可以使用ReaderT读取一些全局配置数据。为了简单起见,假设配置是一个字符串

代码语言:javascript
复制
type NewMonad = ReaderT L.ByteString (ServerPartT IO) 
runNewMonad :: NewMonad a -> L.ByteString -> ServerPart a
runNewMonad k c = runReaderT k c

如何更改hello以便它可以使用ask?我不确定会是什么类型。NewMonad Response并不完全正确,因为ok返回一个ServerPart Response

如何更改main才能使serve正常工作?它需要一个ServerPart Response

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-26 12:46:42

实际上,NewMonad Responsehello的正确类型;您只需要使用lift将底层monad中的操作转换为转换器中的操作即可。例如:

代码语言:javascript
复制
hello :: NewMonad Response
hello = do
    foo <- ask
    lift . ok $ toResponse foo

总体而言,

代码语言:javascript
复制
lift :: (MonadTrans t, Monad m) => m a -> t m a

也就是说,如果你有一个单子动作,那么你就把它变成了这个单子上的任何单子转换器中的一个动作。这是monad transformer的定义:它可以在任何monad上转换,并嵌入该monad的操作。

似乎将所有的单一操作限制在一个特定的monad上-而不是使用类型类在任何适当的monad中工作-与完整的Happstack相比,Happstack lite使用的是简化之一,后者具有this type for ok

代码语言:javascript
复制
ok :: (FilterMonad Response m) => a -> m a

对于这种类型,假设为标准转换器声明了适当的实例,您可以直接在MyMonad中使用ok

至于main,您需要去掉ReaderT层,生成一个可以传递给serveServerPart Response

代码语言:javascript
复制
main :: IO ()
main = do
    serve Nothing $ runNewMonad hello ("Hello" :: L.ByteString)

(如果您使用的是monad承载状态,而您希望在许多请求的过程中更改它,这将会导致问题,因为serve的类型限制太多,无法支持这种状态线程处理(不需要使用IORef或类似的手动编码);可能不受限制的Happstack能够做到这一点,但它很可能非常脆弱,因为您不应该真正依赖于这样处理请求的顺序。)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9014018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档