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.
CodePudding user response:
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.