0

我在假期里花了一点时间在 Haskell 上,但现在我遇到了一个问题。我有一个由布尔值组成的列表,我正在尝试创建一个函数,该函数采用整数列表并在相应位置翻转布尔值。

如果您将以下代码加载到 GHCi 中并尝试运行flipBits testBoard [1,0,2]结果是[True, True, False, False]。如果你用flipBits testBoard [1,2,0]运行它,结果是[True, True, True, False]

我希望结果不依赖于传递给 FlipBits 的列表中数字的顺序(显然列表中的 0 会停止执行)。我究竟做错了什么?

flipBit board which (x:xs)
    | which == 0 = (not (board !! which)):xs
    | otherwise =  x:(flipBit board (which-1) xs)

flipBits board [] = board
flipBits board (x:xs) = flipBits (flipBit board x board) xs

testBoard = take 4 $ repeat False
4

2 回答 2

2

在你的flipBit功能

flipBit board which (x:xs)
    | which == 0 = (not (board !! which)):xs
    | otherwise =  x:(flipBit board (which-1) xs)

board您将要翻转的所有元素替换为not (board !! 0),因为唯一的翻转是在which达到 0 时。

你只是想从中删除一个论点,

flipBit which (x:xs)
    | which == 0 = not x : xs
    | otherwise  = x : flipBit (which - 1) xs

然后有

flipBits board (x:xs) = flipBits (flipBit x board) xs

或者,由于这是一种重复的应用模式,请使用适当的高阶函数,

flipBits board ixs = foldr flipBit board ixs
于 2012-12-23T23:46:14.827 回答
1
    | which == 0 = (not (board !! which)):xs

守卫说 RHS 只有在which为 0 时才会被评估,所以这与

    | which == 0 = (not (board !! 0)):xs

board这是“原始”板,在我们开始沿着它走之前。因此,不是在某个位置翻转该位,而是将该位替换为列表头部的位的倒数。

你应该改为

    | which == 0 = not x : xs

然后问自己为什么需要第一个参数来flipBit.

于 2012-12-23T23:45:16.560 回答