繁体   English   中英

如何用bind&fmap编写此代码?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM