Haskell 如何使用bind&;编写此代码;fmap?
如何使用bind和fmap编写没有do符号的函数事务Haskell 如何使用bind&;编写此代码;fmap?,haskell,Haskell,如何使用bind和fmap编写没有do符号的函数事务 transaction :: UTCTime -> EncUser -> STM (Either Text ()) transaction now user = do dbData <- readTVar db case isValidRequest dbData of Right _ -> do confirmRegistration user
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
…但编译失败,出现下面的错误,我似乎不明白如何在isValidRequest生成的两个结果之上fmap confirmRegistration
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
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
这是在我修改了confirmRegistration的类型之后,在melpomene的注释之后的最终代码。我将此作为参考发布,因为它看起来非常接近我最初想要的东西
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
transaction::UTCTime->Text->EncUser->STM(任意文本())
事务现在rid user=do
readTVar数据库
>>=序列。确认注册用户isValidRequest
其中isValidRequest=findRegistration rid>=>现在确认有效吗
confirmRegistration::EncUser->Registration->STM()
findRegistration::Text->DbData->任一文本注册
isConfirmationValid::UTCTime->注册->任一文本注册
注:运算符为“函子合成”
不过我还是不明白为什么这里需要序列,但我可能应该把它作为一个不同的问题发布 这是在我修改了confirmRegistration的类型之后,在melpomene的注释之后的最终代码。我将此作为参考发布,因为它看起来非常接近我最初想要的东西
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
transaction::UTCTime->Text->EncUser->STM(任意文本())
事务现在rid user=do
readTVar数据库
>>=序列。确认注册用户isValidRequest
其中isValidRequest=findRegistration rid>=>现在确认有效吗
confirmRegistration::EncUser->Registration->STM()
findRegistration::Text->DbData->任一文本注册
isConfirmationValid::UTCTime->注册->任一文本注册
注:运算符为“函子合成”
不过我还是不明白为什么这里需要序列,但我可能应该把它作为一个不同的问题发布 上述表达式的情况非常类似于任何一个的fmap实现,因此这就是为什么我想使用fmap来代替它-of@vidi您不能,因为您有
confirmRegistration user>
。没有它,您可以像这样提取return
:return(case isValidRequest dbData of Right->Right();Left err->Left err)
,这就是返回(fmap(const())(isValidRequest dbData))
。但那不是你所拥有的。现在我意识到这里的确认注册类型是错误的。我会修好类型,然后回来。谢谢同时,您是对的,鉴于原始问题中的类型,上述表达式的大小写与其中一个的fmap实现非常相似,因此这就是为什么我希望使用fmap来代替大小写-of@vidi您不能,因为您有confirmRegistration user>
。没有它,您可以像这样提取return
:return(case isValidRequest dbData of Right->Right();Left err->Left err)
,这就是返回(fmap(const())(isValidRequest dbData))
。但那不是你所拥有的。现在我意识到这里的确认注册类型是错误的。我会修好类型,然后回来。谢谢同时,考虑到原始问题中的类型,你是对的