返回Haskell中的元素序列



我想在Haskell中的游戏中返回一系列卡片。例如:

[(SIX,D),(SEVEN,D),(EIGHT,S)] ~> [(SIX,D),(SEVEN,D)] 
[(SIX,D),(SEVEN,S)] ~> []
[(SIX,D),(SEVEN,D)] ~> [(SIX,D),(SEVEN,D)]

到目前为止,我有这个功能:

findSeq :: [Card] -> [Card]
findSeq [] = []
findSeq (h:t)
    | null t = [h]
    | Just h == (pCard (head t) pack) = h:findSeq t
    | otherwise = [h]

它甚至返回第一张卡:即,不适合上面的示例2。如果没有连续元素的序列,我怎么能返回序列,或者什么都不返回?

我也试着过滤它们,但我收到了"太多的参数异常"。有什么帮助吗?

我会这样做:

import Data.List (groupBy)
import Data.Function (on)
data Suit = Clubs | Diamonds | Hearts | Spades deriving Eq
data Face = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
          | Jack | Queen | King deriving Enum
type Card = (Face, Suit)
findSequences :: [Card] -> [[Card]]
findSequences = [sequence | sequence <- groupBy ((==) `on` snd),
                            contiguous (map fst sequence),
                            length sequence > 1]
contiguous :: Enum a => [a] -> Bool
contiguous (x:xs) = map fromEnum xs == take (length xs) [fromEnum x + 1 ..]

findSequences函数查找牌组中的所有序列(单卡序列除外)。

从数学上讲,将一张牌视为一张牌的序列实际上是完全合理的。因此,不改变这种行为是个好主意。。。只需扩展定义,就可以从中获得真正想要的结果。

真正的问题不是你把单个卡片作为单个元素序列,而是你没有得到它们背后的任何东西。要解决此问题,您不仅需要首先获得列表中的第一个序列,还需要所有序列:

findSeqs :: [Card] -> [[Card]]
findSeqs [] = []
findSeqs [h] = [[h]]
findSeqs (h:t@(h':_))  -- avoid `head` and `null`... pattern matching FTW!
  | Just h == (pCard h' pack)  = h ^: findSeqs t
  | otherwise                  = [h] : findSeqs t

我使用了辅助

(^:) :: a -> [[a]] -> [[a]]
h ^: (hl:ls) = (h:hl) : ls
_ ^: [] = []

一旦你有了findSeqs,你只需要浏览第一个非退化序列的结果。