我正在使用happstack从http请求接收一些参数,然后将这些参数传递到将从数据库中检索数据的函数,并在HTTP响应中返回此数据,如下所示:
myFunc :: IO String
myFunc = do r <- look "personId"
conn <- connectODBC "... my connection string ...";
vals <- quickQuery conn ("SELECT Name FROM Person where Id = ?") [(toSql r)];
return (processData vals)
handlers :: ServerPartT IO Response
handlers = do
x <- liftIO (myFunc);
decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
msum [
dir "getData" $ ok $ toResponse x
, ... other handlers ...
]
mainFunc = simpleHTTP nullConf handlers
但是,当我构建上述代码时,我会收到以下错误:
没有使用"外观"而引起的(hasrqdata io(的实例 在" do"块的stmt中:r&lt; - 查看" persyid"
在阅读了有关类似问题的问题(像这样(之后,我认为我必须在某个地方包括HasRqData
约束,但是我无法学习。
正如您可能猜到的那样,这对单子来说也是一个问题。happstack
中有少数(HasRqData
等(,因此您可能会认为这是一个复杂的情况。
让我们从 innocent-looking look
函数开始。
look :: (Functor m, Monad m, HasRqData m) => String -> m String
确实,有一个非平凡的约束HasRqData
。让我们问自己:什么monads haverqdata ?(碰巧IO
还没有!(
class HasRqData m where
...
Instances
HasRqData RqData
(MonadIO m, MonadPlus m) => HasRqData (ServerPartT m)
...
其他实例是前两个衍生物,因此,似乎我们必须首先考虑这两个选项。
-
RqData
的效果有限 - 您只能执行look
及其衍生物,从当前的请求中提取信息。因为我们还想还具有其他效果 - 查询数据库,这对我们来说还不够。 -
ServerPartT m
是我们同一老朋友ServerPart ≡ ServerPartT IO
的一般形式。碰巧它也是HasRqData
。这不是一个巧合,而是happstack
设计的含义 - 看起来作者意味着我们到处使用这个单一的单子,除非我们需要特殊的粒度。因此,让我们尝试一下。
&nbsp;
myFunc :: ServerPart String
myFunc = do r <- look "personId"
return undefined
此编译。
现在,我们甚至不需要在handlers
中提起myFunc
,我们以前的困境已经解决了。不过,我们需要通过以前讨论的相同 jar逻辑来提高对数据库的访问。
我相信您可以自己弄清楚细节。无论如何,让我知道它是如何工作的!