给定类 X 和 Y,创建彼此类的实例最惯用的方法是什么?例如 -
instance (X a) => Y a where ...
instance (Y a) => X a where ...
我想避免扩展。另外,我知道这可能会导致一些讨厌的无限递归,所以我愿意采用完全不同的方法来完成同样的事情并保持相对干燥。下面给出了一些关于我遇到的确切问题的背景 -
data Dealer = Dealer Hand
data Player = Player Hand Cash
class HasPoints a where
getPoints :: a -> Int
class (HasPoints a) => CardPlayer a where
getHand :: a -> Hand
viewHand :: a -> TurnIsComplete -> Hand
hasBlackjack :: a -> Bool
hasBlackjack player = getPoints player == 21 &&
(length . getCards . getHand) player == 2
busts :: a -> Bool
busts player = getPoints player > 21
我想这样做——
instance (CardPlayer a) => HasPoints a where
getPoints = getPoints . getHand
但看来我必须这样做——
instance HasPoints Dealer where
getPoints = getPoints . getHand
instance HasPoints Player where
getPoints = getPoints . getHand
编辑
似乎我最喜欢的方法是保留类型类HasPoints
并改为实现。CardPlayer
data
data CardPlayer = Dealer Hand | Player Hand Cash
instance HasPoints CardPlayer where
getPoints = getPoints . getHand
getCash :: CardPlayer -> Maybe Cash
getHand :: CardPlayer -> Hand
viewHand :: CardPlayer -> TurnIsComplete -> Hand
hasBlackjack :: CardPlayer -> Bool
busts :: CardPlayer -> Bool
-- I wanted HasPoints to be polymorphic
-- so it could handle Card, Hand, and CardPlayer
instance HasPoints Hand where
getPoints Hand { getCards = [] } = 0
getPoints hand = if base > 21 && numAces > 0
then maximum $ filter (<=21) possibleScores
else base
where base = sum $ map getPoints $ getCards hand
numAces = length $ filter ((Ace==) . rank) $ getCards hand
possibleScores = map ((base-) . (*10)) [1..numAces]
instance HasPoints Card where
-- You get the point