バインド& fmapを使用して、do-notationなしでファンクショントランザクションをどのように書くことができますか?このコードを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
...しかし、コンパイルはエラー怒鳴るで失敗し、私はどちらかの結果の上にconfirmRegistrationをFMAPする方法を理解するように見えることはできません
• 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
上記のcase-of式はどちらかのfmap実装と非常によく似ていますので、代わりにfmapを使用したいのですが – vidi
@vidiあなたは 'confirmRegistration user >>'を持っているのでできません。それがなければ 'return(fmap(const()(isValidRequest dbData)')というreturn(これは右の_ - > Right();左エラー - >左エラー) ) '。しかし、それはあなたが持っているものではありません。 – melpomene
ここでconfirmRegistrationのタイプが間違っていることに気付きました。タイプを修正して戻ってきます。ありがとう。一方で、あなたは正しいです、元の質問の種類 – vidi