卡片的类型和颜色:
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
),我将如何?但是它允许自己重新实现它,因为我希望能够在深层次的功能层面上理解如何解决这个问题。
答案 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