在Haskell中编译时解析错误(x + 1)

时间:2013-03-20 12:37:14

标签: parsing haskell compilation

我正在做这项任务,我迫切希望让它发挥作用。 我知道这不是最聪明的方式,而且它不是最有效的方式。我这样做纯粹是因为我想测试这段代码效率低下。

transition_from_conductor :: Element_w_Coord Cell -> List_2D Cell -> Cell
transition_from_conductor element world = case num_of_heads_around_conductor (0, element) world of
    1 -> Head
    2 -> Head
    _ -> Conductor
    where
        num_of_heads_around_conductor :: (Int, Element_w_Coord Cell) -> List_2D Cell -> Int
        num_of_heads_around_conductor (i, (cell, (x, y))) ((w_cell, (w_x, w_y): rest)) = case rest of
            [] -> i
            _  -> case (w_cell, w_x, w_y) of
                (Head, (x + 1),  y)        -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head, (x + 1), (y + 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head, (x + 1), (y - 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head, (x - 1),  y)        -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head, (x - 1), (y + 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head, (x - 1), (y - 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head,  x,      (y + 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                (Head,  x,      (y - 1))   -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
                _                          -> num_of_heads_around_conductor ( i     , (cell, (x, y))) (rest)

如果我尝试在终端中运行它,它会在

上给出解析错误(x + 1)
(Head, (x + 1), y) .....

我做错了什么?以及如何修复它?

一些事情......

type List_2D e = [Element_w_Coord e]
type Element_w_Coord e = (e, Coord)
type Coord = (X_Coord, Y_Coord)
type X_Coord = Integer
type Y_Coord = Integer

谢谢你们:D

2 个答案:

答案 0 :(得分:3)

您使用的是“n + k”模式,该模式已从语言中删除。您不能再使用“+”对整数进行模式匹配。在大多数情况下,模式匹配仅限于构造函数和文字。

为了达到与模式匹配相同的结果,我建议:

(Head, x0,  y)        -> let x = x0 - 1 in ...

请注意,此代码也有更多错误 - 模式匹配重叠。例如:即使有n + k支持,也不存在模式:

(Head, (x + 1),  y)

失败,下一个模式:

(Head, (x + 1), (y + 1))

成功。换句话说,您有许多永远无法执行的案例。

答案 1 :(得分:3)

这里有两件事:

  • 您不能在模式中使用算术表达式
  • 当您尝试对xy进行模式匹配时,您打算将模式的这些部分限制为等于现有的xy变量,但您改为创建新变量xy

我会使用警卫。

_  -> case (w_cell, w_x, w_y) of
    (Head, x', y')
        | x' == x + 1 && y' == y     -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x + 1 && y' == y + 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x + 1 && y' == y - 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x - 1 && y' == y     -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x - 1 && y' == y + 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x - 1 && y' == y - 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x     && y' == y + 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
        | x' == x     && y' == y - 1 -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
    _                                -> num_of_heads_around_conductor ( i     , (cell, (x, y))) (rest)

然后简化:

_  -> case (w_cell, w_x, w_y) of
    (Head, x', y')
        |    x' == x + 1 && (y' == y || y' == y + 1 || y' == y - 1)
          || x' == x - 1 && (y' == y || y' == y + 1 || y' == y - 1)
          || x' == x     &&            (y' == y + 1 || y' == y - 1)
        -> num_of_heads_around_conductor ((i + 1), (cell, (x, y))) (rest)
    _   -> num_of_heads_around_conductor ( i     , (cell, (x, y))) (rest)

毫无疑问,这可以进一步简化。