所有给定物品均拥有该物业

时间:2013-10-27 11:54:19

标签: haskell functional-programming

卡片的类型和颜色:

data CardType = Spades | Clubs | Diamonds | Hearts

data CardColor = Black | Red

cardColor :: CardType -> CardColor

cardColor card =
  case card of Spades -> Black
               Clubs -> Black
               Diamonds -> Red
               Hearts -> Red

type Card = (CardType, CardColor)

我想检查所有卡片的颜色是否相同:

allTheSameColor :: [Card] -> Bool

allTheSameColor cardList = ???

我想知道,如果不使用使用任何库函数(例如filter),我将如何?但是它允许自己重新实现它,因为我希望能够在深层次的功能层面上理解如何解决这个问题。

2 个答案:

答案 0 :(得分:4)

CardColor应来自Eq,以便具有可比性:

data CardColor = Black | Red
                         deriving (Eq)



allTheSameColor :: [Card] -> Bool
allTheSameColor [] = True
allTheSameColor [x] = True
allTheSameColor (x:y:xs) = if (snd x) == (snd y) then allTheSameColor (y:xs)
                           else False          

更准确地说,你怎么说列表中的数字是相同的?不要考虑需要考虑哪些步骤或过程,根据列表元素之间的关系来考虑,以确定列表元素是否相同。这种关系原来是这样的:第一个元素==第二个元素和第二个元素==第三个元素,依此类推,直到列表的长度。

答案 1 :(得分:3)

我在额外列表函数模块中总是拥有的函数是allSameBy。喜欢这个

allSameBy :: (a -> a -> Bool) -> [a] -> Bool
allSameBy _ [] = True
allSameBy eq (x:xs) = all (eq x) xs

可以轻松解决您的问题
allTheSameColor = allSameBy ((==) `on` snd)

或者(效率较低),您可以将allSameBy定义为

allSameBy eq xs = length (groupBy eq xs) <= 1

编辑:或者如果你不想使用任何库函数(和稍微不同的语义)

allSameBy _ [] = True
allSameBy _ [_] = True
allSameBy eq (x:xs@(y:_)) = case eq x y of False -> False; True -> allSameBy eq xs