![](/img/trans.png)
[英]How does this Haskell code work? fmap fmap (,) <*> Just . reverse
[英]How to write this code with bind & fmap?
您如何使用bind和fmap编写不带注解的函数事务?
transaction :: UTCTime -> EncUser -> STM (Either Text ())
transaction now user = do
dbData <- readTVar db
case isValidRequest dbData of
Right _ -> do confirmRegistration user
return $ Right ()
Left err -> return $ Left err
where isValidRequest = registrationExists >=> isConfirmationValid now
confirmRegistration :: EncUser -> STM ()
registrationExists :: DbData -> Either Text Registration
isConfirmationValid :: UTCTime -> Registration -> Either Text Registration
我的尝试遵循以下原则:
transaction :: UTCTime -> EncUser -> STM (Either Text ())
transaction now user = do
readTVar db
>>= return . isValidRequest
>>= fmap (confirmRegistration user)
where isValidRequest = registrationExists >=> isConfirmationValid now
...但是编译失败并显示以下错误消息,我似乎无法理解如何在isValidRequest生成的Either结果的顶部进行fmap ConfirmRegistration
• Couldn't match type 'Either Text' with 'STM' Expected type: Either Text Registration -> STM (Either Text ()) Actual type: STM Registration -> STM (Either Text ()) • In the second argument of '(>>=)', namely 'fmap (confirmRegistration user)' In the expression: do { readTVar db } >>= return . isValidRequest >>= fmap (confirmRegistration user) In an equation for 'transaction': transaction now user = do { readTVar db } >>= return . isValidRequest >>= fmap (confirmRegistration user) where isValidRequest = registrationExists >=> isConfirmationValid now
do
记号是相当机械:
transaction now user =
readTVar db >>= \dbData ->
case isValidRequest dbData of
Right _ -> confirmRegistration user >>
return (Right ())
Left err -> return $ Left err
where isValidRequest = registrationExists >=> isConfirmationValid now
这是最终的代码,在我修正了melpomene的注释之后,确定了ConfirmRegistration的类型之后。 我将其发布为参考,因为它看起来与我最初想要的非常接近。
transaction :: UTCTime -> Text -> EncUser -> STM (Either Text ())
transaction now rid user = do
readTVar db
>>= sequence . confirmRegistration user <.> isValidRequest
where isValidRequest = findRegistration rid >=> isConfirmationValid now
confirmRegistration :: EncUser -> Registration -> STM ()
findRegistration :: Text -> DbData -> Either Text Registration
isConfirmationValid :: UTCTime -> Registration -> Either Text Registration
注意:运算符<。>是此处的 “ functor composition”
仍然我想不到为什么这里需要序列的直觉,但我可能应该将其发布为另一个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.