返回Haskell中的一系列元素

时间:2015-12-05 17:36:30

标签: list 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。如果那里没有连续元素序列,我怎么能返回一个序列呢?

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

2 个答案:

答案 0 :(得分:1)

嗯,从数学角度来看,将一张卡片视为一张卡片序列实际上是完全合理的。所以不要改变这种行为是个好主意......只需扩展定义,这样就可以从中获得真正理想的结果。

真正的问题不在于您将单张卡片视为单元素序列,而是您不会在其后面获得任何内容。要解决这个问题,您需要首先获取列表中的第一个,但所有序列:

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,你只需要略过第一个非简并序列的结果。

答案 1 :(得分:1)

我就是这样做的:

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函数查找套牌中的所有序列(单卡序列除外)。