0

我正在尝试编写简单的休息 API。我使用 Database.SQLite.Simple、Scotty 和 Aeson。我在 ScottyM() 路由函数中遇到数据库查询问题。当我有这样的事情

routes :: [User] -> ScottyM ()
routes allUsers = do
    get "/users/:id" $ do
        id <- param "id"
        json ([x | x <- allUsers, userId x == id] !! 0)

main = do
    conn <- open "data.db"
    users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
    scotty 3000 (routes users)

一切正常,但在这种情况下 allUsers 只会在服务器启动时更新一次。每次有人询问时,我都想查询。所以我写了这个:

routes :: Connection -> ScottyM ()
routes conn= do
   get "/users/:id" $ do
        id <- param "id"
        users <- ( query_ conn "select id, first_name, second_name, team from users" :: IO [User] )
        json (users !! id)

main = do
    conn <- open "data.db"
    scotty 3000 (routes conn)

我收到错误

Couldn't match expected type ‘Web.Scotty.Internal.Types.ActionT
                                Text IO [a0]’
            with actual type ‘IO [User]’
In a stmt of a 'do' block:
  users <- (query_
              conn "select id, first_name, second_name, team from users" ::
              IO [User])
In the second argument of ‘($)’, namely
  ‘do { id <- param "id";
        users <- (query_
                    conn "select id, first_name, second_name, team from users" ::
                    IO [User]);
        json (users !! id) }’
In a stmt of a 'do' block:
  get "/users/:id"
  $ do { id <- param "id";
         users <- (query_
                     conn "select id, first_name, second_name, team from users" ::
                     IO [User]);
         json (users !! id) }

如何解决?另外,如果我想的话,如何将参数传递给 sql 查询select * from users where id = id from parameters

4

1 回答 1

4

函数的get第二个参数是 type ActionM。如果您进一步调查,您会发现这只是更复杂的外观的简写ActionT,带有easTextmas IO

因为您的do块属于这种类型,所以您不能IO直接调用函数。您需要使用liftIO来获得正确的类型。liftIO因此,只需在调用之前添加 a 即可query_修复它。

在项目 wiki 中有一个名为using scotty with IO的示例,它显示了这一点。

于 2016-12-28T14:00:19.283 回答