禁止解析类型

时间:2018-08-11 08:09:55

标签: haskell scotty

我最近才开始在Haskell中进行编码,并且开始使用 do block 。我来自Scala世界,在读了一本书和一些博客之后,我发现禁止访问是我们理解的灵感。但是我仍然在为作为输入->输出传递的每个函数的参数而苦苦挣扎。

在我的代码中,我正在使用scotty http服务器库来获取请求,并且试图将该请求保留在mySQL中。

但是在这一行中,我尝试top从Maybe中获取值,以将其发送给要保留的另一个函数

user <- (fmap (\user -> insertUser user) maybeUser)

由于该函数未返回预期的类型,因此永远不会编译

  

ActionT Text IO(也许是用户)

但是

  

IO用户

这是我的洞程序

createUser :: ActionM ()
createUser =  do maybeUser <- getUserParam
                          -- Persist the user
                          _ <- persistUser
                          json maybeUser

getUserParam :: ActionT Text IO (Maybe User)
getUserParam = do requestBody <- body
                  return (decode requestBody)

persistUser :: Maybe User -> ActionT Text IO (Maybe User)
persistUser _maybeUser = let maybeUser = _maybeUser in do
                           user <- maybeUser
                           user <- (fmap (\user -> insertUser user) maybeUser)
                           return maybeUser

insertUser :: User -> IO User
insertUser _user = let user = _user in do
    conn <- createConnection
    status <- execute conn insertUserQuery [MySQLInt32 (intToInt32 $ getUserId user), MySQLText "hello_haskell_world"]
    return user

1 个答案:

答案 0 :(得分:2)

让我们考虑以下功能:

persistUser :: Maybe User -> ActionT Text IO (Maybe User)

类型为Maybe User的值作为参数传递,我们需要将此用户插入数据库。为此,我们可以将(<$>)(或fmap)函数用作:

insertUser <$> maybeUser

结果类型为:Maybe (IO User)。现在,我们需要以某种方式将lift的类型更改为ActionT Text IO (Maybe User)

Web.Scotty.Trans有一个liftAndCatchIO函数(也可以在Web.Scotty模块中使用),该函数主要完成我们需要的操作,但是它接受IO a作为参数,因此我们需要来“交换” MaybeIO。让我们为此find一个函数。因此sequence会满足我们的需求。

结果,我们实现了persistUser函数的以下实现:

persistUser maybeUser =
    liftAndCatchIO $ sequence $ insertUser <$> maybeUser