做块解析类型
Do block resolve types
我最近才开始 Haskell 编码,并且开始使用 do block。我来自 Scala 世界,在读了一本书和一些博客后,我发现 do block 是我们理解的灵感来源。但我仍然在为每个函数作为输入传递的参数而苦苦挣扎 - >输出
在我的代码中,我使用 scotty http 服务器库来获取请求,并且我试图在 mySQL.
中保留该请求
但是在这一行中,我尝试从 Maybe 中获取值以发送到另一个要持久化的函数
user <- (fmap (\user -> insertUser user) maybeUser)
它永远不会编译,因为函数没有return预期的类型
ActionT Text IO (Maybe User)
但是
IO User
这是我的洞计划
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
让我们考虑以下函数:
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 function (also available in Web.Scotty
module), which mostly does what we need, but it accepts IO a
as an argument, so we need to "swap" Maybe
and IO
. Let's find a function for this. So sequence 可以满足我们的需要。
因此,我们有以下 persistUser
函数的实现:
persistUser maybeUser =
liftAndCatchIO $ sequence $ insertUser <$> maybeUser
我最近才开始 Haskell 编码,并且开始使用 do block。我来自 Scala 世界,在读了一本书和一些博客后,我发现 do block 是我们理解的灵感来源。但我仍然在为每个函数作为输入传递的参数而苦苦挣扎 - >输出
在我的代码中,我使用 scotty http 服务器库来获取请求,并且我试图在 mySQL.
中保留该请求但是在这一行中,我尝试从 Maybe 中获取值以发送到另一个要持久化的函数
user <- (fmap (\user -> insertUser user) maybeUser)
它永远不会编译,因为函数没有return预期的类型
ActionT Text IO (Maybe User)
但是
IO User
这是我的洞计划
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
让我们考虑以下函数:
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 function (also available in Web.Scotty
module), which mostly does what we need, but it accepts IO a
as an argument, so we need to "swap" Maybe
and IO
. Let's find a function for this. So sequence 可以满足我们的需要。
因此,我们有以下 persistUser
函数的实现:
persistUser maybeUser =
liftAndCatchIO $ sequence $ insertUser <$> maybeUser