我有一個型別為[Maybe SomeType]的輸入list和一個型別為SomeType -> Bool的謂詞p,我想回答"謂詞p是否對所有剛好在輸入中的SomeType成立?"
第一部分很簡單:(map . fmap) p list是[Maybe Bool]的型別。
一個重要的資訊是,我知道length list >=1和all isNothing list == False都成立,所以在(map . fmap) p list中至少有一個Bool。
但是我如何從這個串列中抽出一個單一的Bool?
我想我可以利用折疊(例如通過foldl)和Maybe的MonadPlus實體,做一些類似的事情:
allTrueOrNothing :: [Maybe Bool] ->Bool
allTrueOrNothing = fromJust . foldl mplus mzero
但是這并不完全正確,因為mplus如果是Just something就會回傳左邊的運算元,而不管something是什么,所以allTrueOrNothing將回傳True,即使其輸入是[Just True, Just False] 。
我可以用什么最簡潔/最習慣的方式來完成這個任務呢?
我看到我可以簡單地過濾出Nothings,然后和在一起的Justs,像這樣:
allTrueOrNothing'/span> :: [Maybe Bool] -> Bool ::.
allTrueOrNothing' = all fromJust . filter (fmap not isNothing)
但是我更想知道是否有辦法讓那些Maybe Bools表現得像一個Monoid意識到它的Bool內容。
uj5u.com熱心網友回復:
我將直接使用all:
all . all :: (a -> Bool) -> [Maybe a] -> Bool.
如果你因為某些原因必須要有你所描述的相位區分,那么你可以使用特化and = all id:
all and :: [Maybe Bool] -> Bool
uj5u.com熱心網友回復:
這似乎可以作業:
這似乎可以作業。
> and . catMaybes $ [Just False, Nothing, Just False]
False]。
> 和 . catMaybes $ [Just False, Nothing, Just True ]
False]。
> 和 . catMaybes $ [Just True, Nothing, Just True] .
True]。
你可以使用catMaybes將串列轉換為[Bool],并使用and得出結論。
(注意,這將在一個全部是Nothings的串列中回傳True,根據你的假設,這是一個 "不可能 "的情況。)
如果你絕對想使用一個單數,我想你可以這么做,但這有點麻煩。這將涉及到用一些newtype And = And (Maybe Bool)來包裝串列中的每個元素,然后定義相關的單體實體,然后mconcat每個元素,最后解除包裝。
未測驗的代碼:
newtype And = And (Maybe Bool)
instance Semigroup And where
And Nothing <> x = x
x <> And Nothing = x
And (Just a) <> And (Just b) = And (Just (a & & b)
instance Monoid And where
mempty = Nothing
allTrueOrNothing :: [Maybe Bool] ->Bool
allTrueOrNothing = fromMaybe False . coerce . mconcat @And . coerce
uj5u.com熱心網友回復:
最干凈的方法是and .catMaybes。
但是你想使用Monoid,它知道它的Bool內容,以&&的方式。這就是All:
> foldMap (fmap All) [Just True, Nothing,Just False]
Just (All {getAll = False})
> foldMap (fmap All) [Just True, Nothing,Just True]
Just (All {getAll = True})
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/316900.html
標籤:
