Pregunta

I'll still have a lot to learn about Haskell and I am having a bit of trouble with the following code. I can do the following, but of course it creates compiler warnings since not all cases are presented in case address s of, I'd like to make sure those warnings are not there:

postAddTenantR :: Handler Value
postAddTenantR = do
    newTenantData <- parseJsonBody :: Handler (Result NewTenant)
    case newTenantData of
      Success s -> runDB $ do
        newTenantGroup <- insert $ TenantGroup
        _ <- insert $ Tenant (firstName s) (lastName s) (Just newTenantGroup)

        case address s of
          Just newAddress -> do
            newProperty <- insert $ Property newAddress
            insert $ Lease Nothing Nothing Nothing newProperty newTenantGroup

        returnJson $ ProcessingResponse True Nothing
      Error e -> returnJson $ ProcessingResponse False (Just $ pack e)

I am not sure how to do something like Nothing -> do {} or Nothing -> return () that matches the type. If it is Nothing than I don't want to do anything. I also thought to use when but again the compiler doesn't like the return type:

when (isJust $ address s) $ do
  newAddress <- address s
  newProperty <- insert $ Property newAddress
  insert $ Lease Nothing Nothing Nothing newProperty newTenantGroup
¿Fue útil?

Solución

The problem is that both alternatives of a case expression need to have the same type. Since you are ignoring the return value, you can add a return () to the Just case. You should then be able to use return () in the Nothing case as well:

case address s of
  Just newAddress -> do
    ...
    return ()
  Nothing -> return ()

Otros consejos

In cases like this, I might use maybe:

flip (maybe $ return ()) (address s) $ \newAddress -> do
    -- ...

(Though now that I look at that, that isn't the most readable thing, is it? Well, it's good for shorter expressions where you wouldn't need to use flip.)

If you're doing this a lot, you could make a function that encapsulates this sort of behavior:

-- suggested by jozefg in comments
withMaybe :: (Monad m) => Maybe a -> (a -> m ()) -> m ()
withMaybe m f = maybe (return ()) f m
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top