Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用snap中的读卡器monad(或snap中的monad转换器)_Haskell_Monads_Monad Transformers_Haskell Snap Framework - Fatal编程技术网

Haskell 使用snap中的读卡器monad(或snap中的monad转换器)

Haskell 使用snap中的读卡器monad(或snap中的monad转换器),haskell,monads,monad-transformers,haskell-snap-framework,Haskell,Monads,Monad Transformers,Haskell Snap Framework,有人能演示如何在读卡器monad中使用snap monad吗?蒙纳德变形金刚把我搞糊涂了。(或者,我很乐意接受有关monad transformers的教程的建议,以及如何看到光明并最终摸索它们。) 编辑:Oops;忘了具体说明我实际上在做什么,而不是在具体的事情上寻求帮助。战略,而不是战术。我特别希望在所有处理程序之间共享一个数据库连接/池,而不必在指定路由时显式地传递该数据库连接/池。看来读者单子是实现这一点的方法。假设snap单子来自。。。Snap是monad(不是monad转换器),因此

有人能演示如何在读卡器monad中使用snap monad吗?蒙纳德变形金刚把我搞糊涂了。(或者,我很乐意接受有关monad transformers的教程的建议,以及如何看到光明并最终摸索它们。)


编辑:Oops;忘了具体说明我实际上在做什么,而不是在具体的事情上寻求帮助。战略,而不是战术。我特别希望在所有处理程序之间共享一个数据库连接/池,而不必在指定路由时显式地传递该数据库连接/池。看来读者单子是实现这一点的方法。

假设snap单子来自。。。Snap是monad(不是monad转换器),因此不能在任意monad中运行它。如果需要,您可以使用
ReaderT
转换器将读卡器功能嵌入Snap中

runSnap
的类型为

runSnap :: Snap a -> (ByteString -> IO ()) -> (Int -> IO ()) -> Request -> Iteratee ByteString IO (Request, Response)
这告诉我们,它运行在一个
iterateebytestringio
monad中。读卡器monad不允许您在输入流上执行IO或迭代,因此您不能在读卡器monad中运行Snap计算


如果你解释了你想要实现的目标,有人可能会建议一种实现它的方法。

如果你不怕使用GHC特定的扩展,下面是monad transformers的简单方法:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.Reader

data ReaderData = ...

newtype MyMonad a = MyMonad (ReaderT ReaderData Snap a)
  deriving (Monad, MonadReader ReaderData)

runMyMonad :: MyMonad a -> ReaderData -> Snap a
runMyMonad (MyMonad m) r = runReaderT m r

liftSnap :: Snap a -> MyMonad a
liftSnap act = MyMonad (lift act)
您现在可以使用
ask
local
访问读卡器数据。要在
Snap
monad中运行操作,需要将其“提升”到新的monad中

... r <- liftSnap $ ... snap action ...

。。。rSnap具有ApplicationState类型,允许您打包所需的任何应用程序范围的资源(数据库连接、模板引擎等)


它位于生成的文件Application.hs中,默认情况下,ApplicationState中包含HeistState和TimerState。您只需将db连接放在那里,就可以从Snap应用程序中的任何位置使用它。

已更新以反映我真正想要的内容,对此表示抱歉。您甚至不需要
newtype
,它可能只是一个类型同义词:
type MyMonad=ReaderT ReaderData Snap
。然后使用标准的
lift::Snap a->MyMonad a
。我想这里的ReaderData正是我想要的阅读器中的类型?@tehgeekmeister:是的@luqui:根据我的经验,不使用新类型通常会导致以后的问题。这一定是我上次使用的snap版本(我知道,前一段时间是0.2.x左右)之后的新版本,但这正是我想要的。谢谢