我建立了一个函数来验证可折叠结构的所有元素是否相等。

与列表中的类似功能相比,在我看来,更通用的功能非常复杂,但是我无法对其进行简化。

你有什么建议吗?

import Data.Monoid
import Data.Sequence as SQ
import Data.Matrix as MT

allElementsEqualL :: Eq a => [a] -> Bool
allElementsEqualL [] = True
allElementsEqualL (x:ns) = all (== x) ns
-- allElementsEqualL [1,1,1] -> True

allElementsEqualF :: (Foldable t, Eq a) => t a -> Bool
allElementsEqualF xs = case (getFirst . foldMap (First . Just) $ xs) of
                        Nothing -> True
                        Just x  -> all (== x) xs

-- allElementsEqualF [1,1,1] -> True

-- allElementsEqualF $ SQ.fromList [1,1,1] -> True

-- allElementsEqualF $ MT.fromLists [[1,1],[1,1]] -> True

最佳答案

我不知道它的复杂程度如何,但是我认为这是最“干净”的方法。 “干净”是指使用单个特殊的Monoid在结构上进行遍历。

data Same a = Vacuous | Fail | Same a
instance Eq a => Semigroup (Same a) where
    Vacuous    <> x       = x
    Fail       <> _       = Fail
    s@(Same l) <> Same r  = if l == r then s else Fail
    x          <> Vacuous = x
    _          <> Fail    = Fail
instance Eq a => Monoid (Same a) where
    mempty = Vacuous

allEq :: (Foldable f, Eq a) => f a -> Bool
allEq xs = case foldMap Same xs of
                Fail -> False
                _    -> True

关于haskell - 测试可折叠对象的所有元素是否相同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55815807/

10-11 17:41