说,我有一些像这样的代码:
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
功能。
请注意,上面的代码是我的简单方案 代码库。
答案 0 :(得分:5)
我想这对你真正的代码库来说不会令人满意,但是
怎么样 (record :: Maybe Record) <- getRecord
case record of
Just (Record { validate = Just True, mobile = m }) -> do
sendSMS m
_ -> return ()
答案 1 :(得分:2)
您可以将布尔值赋予guard
:
someFunction = do
mrecord <- getRecord
let hasValidated = mrecord >>= validate
case hasValidated >>= guard >> mrecord of
Just record -> do
sendSMS (mobile record)
_ -> return ()
这是一个整洁的解决方案,尽管Daniel Wagner指出它至少执行了一次冗余检查(如果我们将其与Reid Barton's answer进行比较,则检查两次)。只是为了好玩,这是Daniel Wagner's first solution的高尔夫版本:
someFunction = do
mrecord <- getRecord
case mrecord >>= liftA2 fmap (,) validate of
Just (record, True) -> do
sendSMS (mobile record)
_ -> return ()
答案 2 :(得分:2)
让您的验证返回它是否有效以及记录的值:
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
答案 3 :(得分:0)
为什么不进行验证
validate :: Monad m => Record -> MaybeT m Record
getRecord :: Monad m => MaybeT m Record
someFunction = fromMaybe () <$> runMaybeT (getRecord >>= validate >>= doStuff)
使验证在验证时返回记录,或在无效时返回Nothing
。