好吧,所以实际上有一些问题,我会尝试将它们中的每一个单独描述,但从某种意义上说它们都是相关的。
我想插入一个用户ID,我希望从AuthManager
插入。好的,我们可以使用currentUser
然后做一些maybe
voodoo来获取实际的unUid
。但问题何时才开始。好的,我们希望使用execute
来验证查询:
execute "INSERT INTO events(title,recurring) VALUES(?,?);" (eventname,recurring)
动臂即可。好的,然后在执行cabal install
时,它没有说明我没有声明HasPostgres
的实例。因为我的处理程序的类型是...-> ...-> Handler App (AuthManager App)
,所以很有道理。 这是第一个问题:我不知道如何正确地创建实例以使类型正确。 正如我所尝试的那样,只是复制Application.hs
中的初始实例根本无法帮助我们。
这给我们带来了在尝试寻找替代解决方案时出现的其他问题。所以我尝试的解决方案就是用execute
调用替换with pg $ execute
调用。这有以下结果:
Couldn't match type `App' with `AuthManager App'
Expected type: Handler App (AuthManager App) GHC.Int.Int64
Actual type: Handler App App GHC.Int.Int64
再次,无济于事。接下来我尝试删除(AuthManager App)
类型,只需用App
替换它,这样我就可以用AuthManager
替换with auth $ call
次调用。然后我意识到这也不是解决方案,因为一旦你从那里得到AuthManager
,你需要从调用它的每个函数中删除它。
我需要一些帮助来解决这个问题。我可以以某种方式提升类型来解决这个问题吗?或者什么是这个问题的好方法?
修改
好的,所以我试图从我的类型中删除AuthManager App
,所以我毕竟可以使用postgres。现在,这并不像人们期望的那样顺利。下一部分来自Snap init
生成的常规应用程序:
handleLoginSubmit :: Handler App App ()
handleLoginSubmit =
with auth $ loginUser "login" "password" Nothing
(\_ ->handleLogin err) (handleFoo)
where
err = Just "Unknown user or password"
好的,handleLogin
和handleFoo
现在都有Handler App App ()
类型,但是Haskell抱怨它需要类型Handler App (AuthManager App) ()
:
Couldn't match type `App' with `AuthManager App'
Expected type: Handler App (AuthManager App) ()
Actual type: Handler App App ()
--Definition of App:
data App = App
{ _heist :: Snaplet (Heist App)
, _sess :: Snaplet SessionManager
, _auth :: Snaplet (AuthManager App)
, _pg :: Snaplet Postgres
}
答案 0 :(得分:4)
您想使用此类型签名。
yourHandler :: Handler App App ()
with pg $ execute ...
with auth $ loginUser ...
with
函数允许您将Handler b v
函数(只能访问v snaplet的数据)引导到Handler b b
,该函数可以访问所有内容。而它唯一需要做的就是镜头从b到v。
答案 1 :(得分:2)
我写了一个基于Postgres Snaplet的snaplet,所以这对你有用。
instance HasPostgres (Handler App (AuthManager App)) where
getPostgresState = withTop pg get
然后是带有签名的路线:
myRoute :: Handler App (AuthManager App) ()