Код можно исправить, добавив скобки здесь. Обратите внимание, что в случае else
должен получиться пустой список. Например:
returnPossibleMoves stone =
<b>(</b>if testBit (look stone) 0 then [(0,-1)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 1 then [(1,-1)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 2 then [(1,0)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 3 then [(1,1)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 4 then [(0,1)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 5 then [(-1,1)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 6 then [(-1,0)] else <b>[])</b> ++
<b>(</b>if testBit (look stone) 7 then [(-1,-1)] else <b>[])</b>
При этом, выглядит не очень элегантно. Вы можете использовать zip
здесь, чтобы составить 2 кортежа, где вы комбинируете ходы с битом для проверки, а затем filter
свой список. Наконец, вы можете использовать map
, чтобы распаковать 2 кортежа и сохранить первый элемент. Например:
returnPossibleMoves stone = map snd (filter (testBit (look stone) . fst) (zip [0..] moves))
where moves = [(0,-1), (1,-1), (1,0), (1,1), (0,1), (-1,1), (-1,0), (-1,-1)]
или с пониманием списка, как @ chi предлагает :
returnPossibleMoves stone = [move | (i,move) <- zip [0..] moves, testBit (look stone) i]
where moves = [(0,-1), (1,-1), (1,0), (1,1), (0,1), (-1,1), (-1,0), (-1,-1)]
Итак, вот результат:
Prelude Data.Bits> returnPossibleMoves 146
[(1,-1),(0,1),(-1,-1)]
(если мы установим look
в id
).
Это имеет смысл, поскольку для 146
установлены второй, пятый и восьмой биты, и поэтому мы возвращаем второй ((1,-1)
), пятый ((0,1)
) и восьмой ((-1,-1)
) элементы.