我们应该编写一个在炸弹被摧毁后返回游戏区域的函数
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之后的部分)是假的,现在问题我现在如何以交换的值返回整个字段?
使用列表列表或某些不同格式的字段会很容易,但有了这个我就不知道了。
答案 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
希望你能看到如何调整它以适应你在练习中给出的稍微不同(未组合)的类型。