如何检查自定义类型中的所有值是否相等

jke*_*len 1 haskell

我正在寻找一种更好的方法来检查给定类型的所有值是否相等.

例如,考虑:

data Foo = Foo {a :: Int, b :: Int, c :: Int, d :: Int}

allFooEqual :: Foo -> Bool
allFooEqual foo = (a foo == b foo) && (a foo == c foo) && (a foo == d foo)
Run Code Online (Sandbox Code Playgroud)

这可行,但它不是一个可扩展的解决方案.有没有更惯用的方式来执行我所缺少的这种行为?

chi*_*chi 6

替代:

allFooEqual :: Foo -> Bool
allFooEqual (Foo xa xb xc xd) = all (xa==) [xb,xc,xd]
Run Code Online (Sandbox Code Playgroud)

这将进行比较xa == xb && xa == xc && xa == xd.

另一个:

atMostOne :: Eq a => [a] -> Bool
atMostOne xs = and $ zipWith (==) xs (drop 1 xs)

allFooEqual :: Foo -> Bool
allFooEqual (Foo xa xb xc xd) = atMostOne [xa,xb,xc,xd]
Run Code Online (Sandbox Code Playgroud)

这将进行比较xa == xb && xb == xc && xc == xd.

访问"所有Ints in a Foo"可以利用废弃的样板框架或GHC Generics来完成,但除非你真的有很多领域,否则它看起来有点过分.

allFooEqual :: Foo -> Bool
allFooEqual f = atMostOne [ x 
   | Just x <- gmapQ (mkQ Nothing (Just :: Int -> Maybe Int)) f ]
Run Code Online (Sandbox Code Playgroud)

这里有很多类型级别的东西,我强烈推荐它,除非真的,真的需要它.