Search code examples
haskellfunctional-programming

Haskell - Checking in a List of a custom Data type fow Equality


So I have these Data types:

data Player = Black | White deriving Show
data Cell = Piece Player Int | Empty deriving Show
type Board = [[Cell]]

and this instance:

instance Eq Player where
  (==) Black Black = True
  (==) White White = True
  (==) _ _ = False

And I would like to find out the amount of current black pieces on the Board.

I do know if i would like to find out the amount of a specific piece on the Board i could do something like this:

getSpecificPiece :: Board -> [Player]
getSpecificPiece b = concat (map (filter (== Piece Black 170)) b)

How do I look for Pieces of for example the color black if I dont care for the Number ?

concat (map (filter (== Piece Black _ )) b)

This was a was for example something i tried but didn't work.


Solution

  • Edited to add: I'm not entirely sure I answered the correct question; this explains how to count the black pieces, but it'd need some slight modification if you want, e. g., a list of black pieces instead.

    You could do

    countBlackPieces :: Board -> Int
    countBlackPieces = length . filter hasBlackPiece . concat
      where hasBlackPiece (Piece Black _) = True
            hasBlackPiece _               = False
    

    or

    import Data.Maybe (mapMaybe)
    
    getPieceColor :: Cell -> Maybe Color
    getPieceColor (Piece player _) = Just player
    getPieceColor _                = Nothing
    
    countBlackPieces :: Board -> Int
    countBlackPieces = length . filter (== Black) . mapMaybe getPieceColor . concat
    

    I'd probably write the first one, unless I had another use for getPieceColor. You can avoid writing getPieceColor by giving the Player field of Cell a name, but that accessor would be partial (i. e. error out when given Empty), which I think is generally considered a bad idea.

    You may know this, but in case you don't: deriving Eq for Player will result in exactly the Eq instance you've written.