1 year ago

#46708

test-img

staletidings

Binding a Maybe within another monad to avoid case stairway of doom?

I'm fetching a user from a database with a key I'm fetching from an api (uid). The uid is a Maybe ByteString, and so I can either case check whether it's a Maybe and then run the Redis monad, or somehow bind it to DB.hget. Below is an incorrect implementation where the uid is bound to the hget function, but it obviously doesn't work since it's returning a Maybe when it should be a Redis monad. What's an elegant solution to this that avoids verbose case statements?

getUser :: B.ByteString  -> ReaderT LobbyEnv IO User
getUser token =  do
  env <- ask
  uid <- liftIO $ verifyToken token <&> fmap encodeUtf8
  liftIO $ DB.runRedis (env^.db) $ do
    r <- uid >>= DB.hget "users" <&> either (return Nothing) (fmap (BN.decode . BL.fromStrict)) 
    case r of
      Nothing -> throwIO UNKNOWN_ERROR
      Just g -> pure g

haskell

monads

monad-transformers

0 Answers

Your Answer

Accepted video resources