0

我的目标是编写一个名为 walk 的函数,它可以将迷宫单元的值与其邻居切换。例如,调用 walk 0 labyrinthA 应该将 T 单元格向左移动。在这里,我尝试更改 ghci 中迷宫单元的值。

showLabyrinth labyrinth =
   putStrLn $ unlines $ [[labyrinth j i | i <- [1..dimH]] | j <- [1..dimV]]
 where
   dimH = length . takeWhile (/='O') $ [labyrinth 1 i | i <- [1..]]
   dimV = length . takeWhile (/='O') $ [labyrinth i 1 | i <- [1..]]

labyrinthA 9 _  = 'O'
labyrinthA _ 16 = 'X'
labyrinthA _ 17 = 'O'
labyrinthA 1 _  = 'X'
labyrinthA 2 1  = 'X'
labyrinthA 2 8  = 'X'
labyrinthA 2 12 = 'X'
labyrinthA 2 _  = ' '
labyrinthA 3 1  = 'X'
labyrinthA 3 3  = 'X'
labyrinthA 3 5  = 'X'
labyrinthA 3 6  = 'X'
labyrinthA 3 8  = 'X'
labyrinthA 3 9  = 'X'
labyrinthA 3 10 = 'X'
labyrinthA 3 12 = 'X'
labyrinthA 3 14 = 'M'
labyrinthA 3 _  = ' '
labyrinthA 4 1  = 'X'
labyrinthA 4 2  = 'X'
labyrinthA 4 3  = 'X'
labyrinthA 4 5  = 'X'
labyrinthA 4 6  = 'X'
labyrinthA 4 12 = 'X'
labyrinthA 4 _  = ' '
labyrinthA 5 1  = 'X'
labyrinthA 5 5  = 'X'
labyrinthA 5 8  = 'X'
labyrinthA 5 9  = 'X'
labyrinthA 5 10 = 'X'
labyrinthA 5 12 = 'X'
labyrinthA 5 13 = 'X'
labyrinthA 5 15 = 'X'
labyrinthA 5 _  = ' '
labyrinthA 6 1  = 'X'
labyrinthA 6 3  = 'X'
labyrinthA 6 4  = 'X'
labyrinthA 6 5  = 'X'
labyrinthA 6 7  = 'X'
labyrinthA 6 8  = 'X'
labyrinthA 6 10 = 'X'
labyrinthA 6 _  = ' '
labyrinthA 7 1  = 'X'
labyrinthA 7 6  = 'T'
labyrinthA 7 9  = 'X'
labyrinthA 7 10 = 'X'
labyrinthA 7 11 = 'X'
labyrinthA 7 12 = 'X'
labyrinthA 7 13 = 'X'
labyrinthA 7 14 = 'X'
labyrinthA 7 15 = 'X'
labyrinthA 7 _  = ' '
labyrinthA 8 6  = 'E'
labyrinthA 8 _  = 'X'

现在我试着让'T'用 walk 0 labyrinthA 向左走

walk direction labyrinth | direction == 0 = let labyrinth (yKoord 'T') 
(xKoord 'T') = ' ' && let labyrinth (yKoord) ((xKoord+1)) = 'T'
                          | direction == 1 = undefined
                          | direction == 2 = undefined
                          | direction == 3 = undefined 

其中 yKoord 和 xKoord 是整数。
在此处输入图像描述

4

1 回答 1

2

您遇到的错误是因为模式并未涵盖所有情况。穷举模式是穷尽所有可能性的模式,即为每个潜在输入值返回一个结果。

在这里,如果你打电话,例如,会发生什么labyrinthA 10 1?或者labyrinthA 0 0?如果您的编译器在编译时没有警告您有关此错误,您可能希望使用-Wall标志进行编译以打开警告。

如果程序逻辑无法使用任何其他值调用函数(在这种情况下,它可能应该是只能从一个地方调用的本地函数),有一个快速修复。在函数的底部添加这样的行:

labyrinthA x y = error $ "Domain error: labyrinthA " ++ show x ++
                         " " ++ show y

这添加了一个包罗万象的子句,匹配尚未涵盖的任何模式,从而满足编译器的要求。如果函数确实以“不可能”的值调用,则逻辑错误现在将使程序崩溃,并显示更多信息的调试消息。

在您的情况下,您未向我们展示的程序的其他一些部分使用其域之外的值调用您的函数,这会给您带来运行时崩溃。不幸的是,如果不能查看代码,我们将无法为您提供帮助,但是跟踪导致崩溃的调用顺序将是一个很好的第一步。

在这个特定的例子中,您可能不想在玩家每次迈出一步时更新您的迷宫地图。在函数式语言中,这不是一个非常有效或优雅的操作。相反,您可以存储不可变地图,然后更新玩家的位置,以在其上绘制。(X,Y) 坐标可以是您传递的另一个参数或程序状态数据的一部分。

这并不能回答您关于在定义函数后修改函数的问题。我认为这是一个 XY 问题,但这是对这部分问题的字面回答。您不能对String类型执行此操作。在 Haskell 中有一些方法可以获取可变状态,例如Data.Vector.MVector具有ST类型的可变状态,但这不是您的直接问题。

于 2019-04-21T17:09:16.960 回答