【发布时间】:2021-11-08 21:22:30
【问题描述】:
我有一个list 类型的[Maybe SomeType] 输入和一个谓词p 类型SomeType -> Bool,我想回答这个问题“谓词p 是否适用于所有SomeType s 恰好在输入中?”.
第一部分很简单:(map . fmap) p list 的类型为 [Maybe Bool]。
一个重要信息是我知道length list >= 1 和all isNothing list == False 都成立,所以(map . fmap) p list 中必须至少有一个Just True。
但是如何从该列表中取出一个 Bool?
我认为我可以利用折叠(例如通过foldl)和Maybe 的MonadPlus 实例,执行以下操作:
allTrueOrNothing :: [Maybe Bool] -> Bool
allTrueOrNothing = fromJust . foldl mplus mzero
但这并不完全正确,因为如果mplus 是Just something,则不管something 是什么,它都会返回左操作数,所以allTrueOrNothing 将返回True,即使它的输入是[Just True, Just False]。
我可以完成任务的最干净/最惯用的方式是什么?
我发现我可以简单地将filter 取出Nothings,然后将and 放在一起Justs,如下所示:
allTrueOrNothing' :: [Maybe Bool] -> Bool
allTrueOrNothing' = all fromJust . filter (fmap not isNothing)
但我更想知道是否有办法让 Maybe Bools 的行为像 Monoid 一样知道其 Bool 内容。
【问题讨论】:
-
您能在映射
p之前 获取Nothing值吗?all p . catMaybes。由于all p [] == True,原始输入中是否至少有一个非Nothing值无关紧要。
标签: haskell functional-programming monads maybe monadplus