为什么在此Haskell'else if'语句中出现解析错误?

问题描述 投票:0回答:2

我正在寻找有关此代码块为何在块中的第一个else if语句上不断收到解析错误的提示或解释。它说可能是缩进或括号有问题,但我似乎找不到它们。因此,我正在寻找另一组经验丰富的眼睛来使我走上正确的道路。我觉得我忽略了一些很小的东西,但是似乎找不到。这是针对数独求解器的(我承认整个数独求解器是一个类的作业。这是我第一次发布,因此我不是100%确定这是否是一个可以接受的问题,如果不是,请让我知道。)

此功能是获取数独游戏板(基本上是列表的列表)和两个整数,它们是您正在查看的棋盘的3x3部分的坐标,然后从该3d3部分返回数字序列板。

我知道这不是解决该问题的哈斯克尔式方法(我最终还是蛮横地强迫了它),我真的只是在学习Haskell了几周,但我想弄清楚为什么其他情况会如雨后春笋般冒出来一个错误。

getBox :: Board -> Int -> Int -> Sequence
getBox b x y = do
  let i = x
  let j = y


  let x0 = b!!0
  let x1 = b!!1
  let x2 = b!!2
  let x3 = b!!3
  let x4 = b!!4
  let x5 = b!!5
  let x6 = b!!6
  let x7 = b!!7
  let x8 = b!!8

  if (i==0 && j==0)
      then let z = [x0!!0, x0!1, x0!!2, x1!!0 x1!!1, x1!!2, x2!!0, x2!!1, x2!!2]
  else if (i==0 && j==1)
      then let z = [x0!!3, x0!4, x0!!5, x1!!3 x1!!4, x1!!5, x2!!3, x2!!4, x2!!5]
  else if (i==0 && j==2)
      then let z = [x0!!6, x0!7, x0!!8, x1!!6 x1!!7, x1!!8, x2!!6, x2!!7, x2!!8]
  else if (i==1 && j==0)
      then let z = [x3!!0, x3!!1, x3!!2, x4!!0, x4!!1, x4!!2, x5!!0, x5!!1, x5!!2]
  else if (i==1 && j==1)
      then let z = [x3!!3, x3!!4, x3!!5, x4!!3, x4!!4, x4!!5, x5!!3, x5!!4, x5!!5]
  else if (i==1 && j==2)
      then let z = [x3!!6, x3!!7, x3!!8, x4!!6, x4!!7, x4!!8, x5!!6, x5!!7, x5!!8]
  else if (i==2 && j==0)
      then let z = [x6!!0, x6!!1, x6!!2, x7!!0, x7!!1, x7!!2, x8!!0, x8!!1, x8!!2]
  else if (i==2 && j==1)
      then let z = [x6!!3, x6!!4, x6!!5, x7!!3, x7!!4, x7!!5, x8!!3, x8!!4, x8!!5]
  else let z = [x6!!6, x6!!7, x6!!8, x7!!6, x7!!7, x7!!8, x8!!6, x8!!7, x8!!8]
parsing haskell sudoku
2个回答
4
投票

只需删除let z =出现的所有位置,您就可以下一个错误。


0
投票

let表达式具有绑定和主体。典型的let表达式是:

let x = 2 in x + x
    ^^^^^    ^^^^^
   binding    body

这仅意味着2替换为x在正文中。这就是let的全部意思(也就是说,您始终可以通过替换来手动摆脱let)。 let块中允许使用do的语法,这有点模糊,可能会给人以为它就像命令式语言中的可变变量,但不是。

do 
    let i = x
    let j = y
    pure (i + j)

手段

let i = x in 
  let j = y in 
    pure (i + j)

即,let的主体是do块的其余部分。

任何变量都可以追溯到单个唯一定义或函数参数。不能像尝试那样通过多个不同的let语句动态地定义变量。您只需定义一次z。在您的情况下,可以使用guards完成,这是进行条件定义的一种方法。

let z
    | i == 0 && j == 0 = [x0!!0, x0!!1, -- oh my god I am not typing this
    | i == 0 && j == 1 = [x0!!3, x0!!4, -- more?
    | ...

您也可以在没有警卫的情况下完成此操作,只需要将if链移动到let中:

let z = if i == 0 && j == 0 then [...]
        else if i == 0 && j == 1 then [...]
        ...

我希望这会有所帮助。希望您的强力解决方案所带来的痛苦能够得到分摊。

© www.soinside.com 2019 - 2024. All rights reserved.