0

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

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

但是在这一行中,我尝试从 Maybe 中获取值以发送到另一个要持久的函数

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

它永远不会编译,因为函数没有返回预期的类型

ActionT 文本 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
4

1 回答 1

2

让我们考虑以下函数:

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

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

insertUser <$> maybeUser

结果类型为:Maybe (IO User). 现在我们需要以某种方式提升这种类型。ActionT Text IO (Maybe User)

Web.Scotty.Trans有一个liftAndCatchIO函数(在Web.Scotty模块中也可用),它主要做我们需要的,但它接受IO a作为参数,所以我们需要“交换”MaybeIO. 让我们为此找到一个函数。所以序列做我们需要的。

因此,我们有以下persistUser函数的实现:

persistUser maybeUser =
    liftAndCatchIO $ sequence $ insertUser <$> maybeUser
于 2018-08-11T09:50:07.877 回答