对于haskell,如果按照下面给出的话,有没有办法计算黑块的数量。
initialBoard =
Board
[ Just (Black, 2)
, Nothing
, Nothing
, Nothing
, Just (Black, 2)
, Just (White, 5)
, Nothing
, Just (White, 3)
, Nothing
, Nothing
, Nothing
, Just (Black, 5)
, Just (White, 5)
, Nothing
, Nothing
, Nothing
, Just (Black, 3)
, Nothing
, Just (Black, 5)
, Nothing
, Nothing
, Nothing
, Nothing
, Just (White, 2)
]
我是haskell的新手,我想知道haskell是否有像python中的for ... in ...循环这样的函数,允许我检查列表中的每一项。谢谢
答案 0 :(得分:3)
使用filter
删除所有Nothing
和Just (White, _)
值,然后计算剩下的内容。
isBlack :: Maybe (Color, Int) -> Bool
isBlack (Just (Black, _)) = True
isBlack _ = False
countBlacks :: Board -> Int
countBlacks = length . filter isBlack
有点长,但“明显”,单行定义可能
import Data.Maybe (isJust, fromJust)
-- 1. Get rid of Nothings
-- 2. Extract the tuples from the Just values
-- 3. Extract the colors from the tuples
-- 4. Get rid of the Whites
-- 5. Count what's left.
countBlacks = length . filter (== Black) . map fst . map fromJust . filter isJust
或
countBlacks = length . filter (== Black) . map (fst . fromJust) . filter isJust
或
countBlacks = length . filter ((== Black) . fst . fromJust) . filter isJust
利用身份
map f . map g == map (f . g)
filter f . map g == filter (f . g)
请注意fromJust
应谨慎使用; fromJust Nothing
未定义,将引发错误。在这里,它是安全的,因为filter isJust
保证将fromJust
值应用于Just
值。
更安全的替换是maybe
函数,它提供给定Nothing
的默认值。 (您可以将fromJust
视为实施为maybe undefined id
。)
countBlacks = length . filter (maybe False f)
where f (Black, _) = True
f _ = False
因为maybe False f Nothing
评估为False
。
答案 1 :(得分:3)
chepner建议或多或少地建议您过滤Just
,然后过滤Black
。
我建议您将列表[Maybe (Color,Int)]
转换为具有相同答案的[Color]
,然后过滤并计算:
countBlacks = length . filter (== Black) . map (maybe White fst)
^ ^
| -- Just (x, _) ~> x
| -- Nothing ~> White
--- list ~> [Black, Black ... Black]
作为替代方案,您可以转换为代表黑色或白色的一个或零的[Int]
和总和:
countBlacks = sum . map (maybe 0 (fromEnum . (== Black) . fst))
答案 2 :(得分:3)
进行编译的一些设置:
data Color = Black | White deriving Eq
newtype Board = Board [Maybe (Color, Int)]
一次解决一小块;一步到位就没有勇气解决问题。继续寻找改变你拥有的数据的方法,丢弃信息,直到你只剩下你想要的东西为止。
也许从一个只获取棋盘上的棋子的功能开始,从而丢弃我们不关心的位置信息:
import Data.Maybe (catMaybes)
-- | Produce a list of all the pieces on a board.
boardPieces :: Board -> [(Color, Int)]
boardPieces (Board xs) = catMaybes xs
我们只对一种颜色的碎片感兴趣,那么如何获取一个碎片列表并仅返回该颜色的碎片类型的函数 - 从而丢弃有关我们不会生成的另一种颜色的碎片的信息关心。
-- | Given a list of pieces with colors, produce a list
-- that only contains the pieces for a particular color.
filterByColor :: Color -> [(Color, Int)] -> [Int]
filterByColor x = filter (\(y, i) -> x == y)
为了弄清楚棋盘上的黑棋数量,我们可以
-- | The number of black pieces on the board.
numBlacks :: Board -> Int
numBlacks = length . filterByColor Black . boardPieces
测试:
λ> numBlacks initialBoard
5