我最近才开始在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
答案 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
作为参数,因此我们需要来“交换” Maybe
和IO
。让我们为此find一个函数。因此sequence会满足我们的需求。
结果,我们实现了persistUser
函数的以下实现:
persistUser maybeUser =
liftAndCatchIO $ sequence $ insertUser <$> maybeUser