哈斯克尔的战列舰(初学者)

时间:2017-09-19 10:32:09

标签: haskell

我们应该编写一个在炸弹被摧毁后返回游戏区域的函数

bombOn x y field -> field(bombed),字段如下所示:

fieldA :: Int -> Int -> Int
fieldA 1 1 = 0
fieldA 1 2 = 1
fieldA 1 3 = 0
fieldA 2 1 = 2
fieldA 2 2 = 0
fieldA 2 3 = 0
fieldA 3 1 = 1
fieldA 3 2 = 0
fieldA 3 3 = 2
fieldA _ _ = -1

我的想法是:

bombOn x y field = if field x y == 0 then field else let field x y = 0 in field

但这显然不起作用,因为我的返回(in之后的部分)是假的,现在问题我现在如何以交换的值返回整个字段

使用列表列表或某些不同格式的字段会很容易,但有了这个我就不知道了。

1 个答案:

答案 0 :(得分:5)

因此,您使用的是高阶编码:字段表示为函数。让我定义一些类型的同义词来澄清一点:

type Coords = (Int, Int)
type Field = Coords -> Int

fieldA :: Field
fieldA (1, 1) = 0
fieldA (1, 2) = 1
fieldA (1, 3) = 0
fieldA (2, 1) = 2
fieldA (2, 2) = 0
fieldA (2, 3) = 0
fieldA (3, 1) = 1
fieldA (3, 2) = 0
fieldA (3, 3) = 2
fieldA _ = -1

(我已经调整fieldA来取一个参数元组,而不是两个讨论的论点。我认为这样可以更容易地看出哪个Int是哪个。)

更新功能意味着什么?这意味着创建一个新函数,它与旧函数的某些参数不同。在这个例子中,我们想要创建一个新函数,在轰炸点返回0,但在所有其他情况下委托给旧字段。

bombAt :: Coords -> Field -> Field
bombAt bombCoords oldField = \coords ->
    if coords == bombCoords
    then 0
    else oldField coords

您可以通过将lambda替换为普通旧参数并使用guard子句代替if来稍微清理此定义。

bombAt :: Coords -> Field -> Field
bombAt bombCoords oldField coords
    | bombCoords == coords = 0
    | otherwise            = oldField coords

希望你能看到如何调整它以适应你在练习中给出的稍微不同(未组合)的类型。