在haskell中使用警卫时的多个条件

时间:2017-06-03 00:25:31

标签: haskell

我正在努力确定一个有效的举措。移动必须满足两个条件才能使其成为有效的移动。第一个条件是确保在我想要移动的位置上没有现有的棋子,第二个条件是确保我在移动时得分。

我已经完成了第一个条件的代码,但我不知道如何在第二个条件下执行此操作。也许之所以困难,是因为它返回了一个Bool,当满足其他条件之一时,需要将其设置为True或False。例如

valid :: Piece -> Pieces -> Bool
valid p [] = True
valid p (x:xs) | getPos(p) == getPos(x) = False
                       | otherwise = valid p xs

你可以看到,我已经完成了第一个条件的代码,现在我该如何添加第二个条件?

这样的东西
valid :: Piece -> Pieces -> Bool
valid p [] = True
valid p (x:xs) | getPos(p) == getPos(x) = False
                       | otherwise = valid p xs
                       && ...

但是,如果第一个条件失败或通过,此函数将停止。这是为了解决这个问题吗?

编辑:声明

data Piece = Piece Position Player
type Pieces = [Piece]

编辑:getPos

getPos是一个检索作品位置的函数

1 个答案:

答案 0 :(得分:4)

您可以将空位置的测试移动到辅助函数(例如vacant)并在valid中写下您的其他条件,例如使用其他score函数:< / p>

valid :: Piece -> Pieces -> Bool
valid p xs = vacant p xs && score p xs > 0

vacant :: Piece -> Pieces -> Bool
vacant p [] = True
vacant p (x:xs)
  | getPos p == getPos x = False
  | otherwise = vacant p xs

score :: Piece -> Pieces -> Int
score p xs = error "TODO"

您还可以更简单地表达vacant,避免显式递归:

import Data.List (notElem)

vacant p xs = getPos p `notElem` map getPos xs

但是,我猜计算得分取决于这一举动是否可行。因此,您可能会发现将其转换为单个函数是一种改进,该函数测试具有正分数的有效移动并返回Maybe

score :: Piece -> Pieces -> Maybe Int
score p xs
  | getPos p `notElem` map getPos xs = let
    computedScore = error "TODO"
    in if computedScore > 0
      then Just computedScore
      else Nothing

  | otherwise = Nothing

现在,您可以对score的结果进行模式匹配:如果您获得Nothing,那么移动无效或未获得正分数;如果您获得Just s,则此移动有效并产生得分s