Haskell: Существуют ли другие вещи, такие как «_», которые вы можете использовать, чтобы сказать, что вам все равно, какова ценность? - PullRequest
2 голосов
/ 24 октября 2011

Итак, я написал игру с шестигранной копией и пытаюсь создать функцию, которая возвращает True, если доска находится в выигрышном состоянии, на данный момент она выглядит следующим образом:

checkWin :: BoardState -> Bool
checkWin b1@(blackPieces,whitePieces,turn,size,win)
  |(length blackPieces) == 0 = True
  |(length whitePieces) == 0 = True
  |length (generateMoves b1) == 0 = True
  |otherwise = False

Так что это работает, если не осталось чёрных или белых фигур или если никто не может сделать ход, но это не сработает, если пешка противника достигнет конца доски (еще один способ выиграть в гексапоне). Переменные blackPieces и whitePieces представляют собой список координат, т.е. [(1,1), (2,1), (3,1)] того, где эти пешки находятся на доске размер n ( поворот истинно, если его белые поворачиваются)

Мне хотелось добавить эти условия в метод, но компилятору это не понравилось.

  |(_,1) `elem` whitePieces = True
  |(_,size) `elem` blackPieces = True

Есть ли другой способ сказать: "Есть ли в whitePieces какие-либо кортежи, у которых вторым элементом является 1 (то есть достиг другой стороны доски)".

Заранее благодарим за ваши полезные комментарии.

Ответы [ 3 ]

7 голосов
/ 24 октября 2011

Итак, нам нужна функция, которая получает список чего-то [a], предикат для чего-то (a->Bool) и возвращает Bool. Быстрая проверка на Hoogle и мы вернемся

any :: (a -> Bool) -> [a] -> Bool
Applied to a predicate and a list, any determines if any element of
the list satisfies the predicate. For the result to be False, the list must be finite

Итак

 (_,1) `elem` whitePieces 

становится

 any (\(_, x) -> x == 1) whitePieces

или (как напоминает мне eternalmatt)

any (==1) ( map snd whitePieces )

и т. Д.


Кстати, лучший способ проверить, пуст ли список, - это сопоставление с образцом или функция null. Метод length == 0 будет проходить по всему связанному списку и может даже войти в бесконечный цикл, если список бесконечен.

2 голосов
/ 24 октября 2011

Причина, по которой компилятору это не нравится, заключается в том, что _ работает только на совпадениях с шаблоном .Подчеркивание означает, что «я мог бы связать эту часть данных с именем переменной, но мне это не нужно».

Способ, которым вы пытались использовать его, отличается: вы в основномсказал " существует ли * x такой, что (x,1) является элементом whitePieces?"

Можете ли вы увидеть разницу?См. Также Haskell 2010> Выражения # Patter Matching

2 голосов
/ 24 октября 2011

вы можете, например, использовать filter:

not $ null (filter wincond whitePieces)
    where wincond x = snd x == 1

это выражение равно True, если список whitePieces со второй записью 1 не является пустым списком ([])

или вы можете использовать map:

or (map (\x -> snd x == size) blackPieces)

это выражение выполняет: сначала проверяется, имеет ли элемент blackPieces вторую запись, равную size, и выдает списокTrues и Falses ([Bool]), тогда функция or дает True, если любой из них равен True

...