删除 fromJust 的使用

Removing the usage of fromJust

说,我有一些这样的代码:

data Record = Record {
  validate :: Maybe Bool,
  mobile :: Text
}

someFunction :: Monad m => m ()
someFunction = do
  (record :: Maybe Record) <- getRecord
  let hasValidated = join $ validate <$> record
  case hasValidated of
     Just True -> do
        sendSMS (mobile $ fromJust record)
     _ -> return ()

现在当 hasValidate 有一些 Just _ 的值时,我可以肯定地知道 record 不是 Nothing。有没有办法删除 fromJust 不使用多个案例或不更改签名 sendSMS 函数。

注意上面的代码是我的一个简单的场景 代码库。

我想这对您的实际代码库来说可能不太令人满意,但是

  (record :: Maybe Record) <- getRecord
  case record of
     Just (Record { validate = Just True, mobile = m }) -> do
        sendSMS m
     _ -> return ()

为什么不进行验证

validate :: Monad m => Record -> MaybeT m Record
getRecord :: Monad m => MaybeT m Record

someFunction = fromMaybe () <$> runMaybeT (getRecord >>= validate >>= doStuff)

这样验证 returns 记录如果有效或 Nothing 无效时。

您可以将布尔值赋给 guard

someFunction = do
    mrecord <- getRecord
    let hasValidated = mrecord >>= validate
    case hasValidated >>= guard >> mrecord of
        Just record -> do
            sendSMS (mobile record)
        _ -> return ()

这是一个简洁的解决方案,但正如 Daniel Wagner 指出的那样,它至少执行了一次冗余检查(如果我们将其与 ). Just for fun, here is a golfed version of :

进行比较,则执行两次冗余检查
someFunction = do
    mrecord <- getRecord
    case mrecord >>= liftA2 fmap (,) validate of
        Just (record, True) -> do
            sendSMS (mobile record)
        _ -> return ()

验证return 是否有效以及记录的值:

someFunction = do
  mrecord <- getRecord
  let hasValidated = do
        record <- mrecord
        valid <- validated record
        return (valid, record)
  case hasValidated of
     Just (True, record) -> do
        sendSMS (mobile record)
     _ -> return ()

完成此更改后,您可以稍微重构一下:

someFunction = do
  mrecord <- getRecord
  traverse_ (sendSMS . mobile) $ do
    record <- mrecord
    True <- validated record
    return record