带有mysql简单的Scotty api in haskell

时间:2017-12-12 13:04:39

标签: mysql haskell scotty

我正在关注this教程,该教程使用scotty和persistent来创建一个简单的API。

但是,我正在尝试使用scotty和mysql简单库创建一个简单的api。

现在我陷入了代码中的某一点。

在下面的代码中,我无法将 getUser 函数转换为输入&#34; ActionT错误配置&#34; ,因为我的代码失败了。< / p>

任何人都可以帮助我理解如何转换getUser函数以实现所需的类型签名吗?

代码

type Error = Text
type Action = ActionT Error ConfigM ()

config :: Config
config = Config
    { environment = Development 
     ,db1Conn = connect connectionInfo
    }

main :: IO ()
main = do
  runApplication config

runApplication :: Config -> IO ()
runApplication c = do
  o <- getOptions (environment c)
  let r m = runReaderT (runConfigM m) c
  scottyOptsT o r application

application :: ScottyT Error ConfigM ()
application = do
  e <- lift (asks environment)
  get "/user" getTasksA

getTasksA :: Action
getTasksA = do
    u <- getUser
    json u 

getUser :: IO User
getUser = do
  e <- asks environment
  conn <- db1Conn config 
  [user]<- query_ conn "select login as userId, email as userEmail from member limit 1"
  return user 

错误

• Couldn't match type ‘IO’ with ‘ActionT Error ConfigM’
      Expected type: ActionT Error ConfigM User
        Actual type: IO User
    • In a stmt of a 'do' block: u <- getUser
      In the expression:
        do { u <- getUser;
             json u }
      In an equation for ‘getTasksA’:
          getTasksA
            = do { u <- getUser;
                   json u }

1 个答案:

答案 0 :(得分:2)

您遗漏了大量代码(导入和编译指示以及User的定义,请在下次加入 - 请参阅MCVE

但现在问你的问题:

我会将Action类型更改为以下

type Action a = ActionT Error ConfigM a

然后getTasksA具有以下类型签名

getTasksA :: Action ()
getTasksA = do
    u <- getUser
    json u 

(或者您可以将其写为getTasksA = getUser >>= json

getUser

getUser :: Action User
getUser = do
  e <- asks environment
  conn <- db1Conn config 
  [user] <- liftIO $ query_ conn "select login as userId, ..."
  return user

一些评论

  • [user] <- liftIO $ query ..是一个坏主意 - 如果找不到用户会导致应用程序崩溃 - 尝试编写总函数和模式匹配。最好返回Maybe User

    getUser :: Action (Maybe User)
    getUser = do
      e <- asks environment
      conn <- db1Conn config 
      fmap listToMaybe . liftIO $ query_ conn "select login as userId, ..."
    
  • 如果你能绕过它,而不是使用persistent而不是手工编写SQL查询 - 这很容易出错,特别是在重构时,想象一下将userId重命名为{ {1}}。

  • userID几次ask但不使用它。使用environment或甚至-Wall进行编译以获取警告甚至提升警告以编译错误(这对于生产设置来说是个好主意。