Haskell:案例中的定义冲突

时间:2018-03-26 16:43:30

标签: haskell

我在Conflicting definitions for 'boardSize'但未isCornerPos获得isCornerPos'。为什么呢?

boardSize :: Int
boardSize = 8

isCornerPos :: Position -> Bool
isCornerPos (i, j) =
    case (i, j) of
        (1, 1)                  -> True
        (1, boardSize)          -> True
        (boardSize, 1)          -> True
        (boardSize, boardSize)  -> True -- problem with this line
        _ -> False

isCornerPos' :: Position -> Bool
isCornerPos' (i, j) =
    case (i, j) of
        (1, 1) -> True
        (1, 8) -> True
        (8, 1) -> True
        (8, 8) -> True
        _ -> False

2 个答案:

答案 0 :(得分:3)

->左侧的名称是要匹配的模式,而不是要使用的变量。匹配模式时,文字只能匹配自身,但变量匹配任何,并且该值被赋予 变量。这意味着您的(1, boardSize) -> True匹配第一个元素为1的任何元组,并将boardSize设置为等于右侧大小的表达式中的第二个元素。

它与定义函数时的工作方式相同,其中isCornerPos (i,j) = ...分别将参数元组的两个元素分配给ij,而不是尝试匹配反对参数的现有值ij。实际上,这与<{1}}表达式中的完全相同,因为函数定义使用语法糖代替case匹配。

case

只是

的缩写
isCornerPos (i,j) = ...

使用isCornerPos = \x -> case $x of (i,j) -> ... 的标准方法是使用警卫:

boardSize

或者将它与模式匹配结合起来:

isCornerPos :: Postion -> Bool
isCornerPos (i,j) | i == 1 && j == 1 = True
                  | i == 1 && j == boardSize = True
                  | i == boardSize && j == 1 = True
                  | i == boardSize && j == BoardSize = True
                  | otherwise = False

我会定义一个辅助函数,并在没有警卫的情况下编写它。

isCornerPos :: Postion -> Bool
isCornerPos (1,1) = True
isCornerPos (1,j) = j == boardSize
isCornerPos (i,1) = i == boardSize
isCornerPos (i,j) = i == boardSize && j == boardSize

答案 1 :(得分:2)

模式匹配引入了 new 变量。您将boardSize重新声明为本地新变量。请使用新的变量名称,并使用警卫将其约束为boardSize。 E.g。

case (i, j) of
        (1, 1)                  -> True
        (1, y) | y == boardSize -> True
        (x, 1) | x == boardSize -> True
        (x, y) | x == boardSize && y == boardSize -> True 
        _ -> False

请注意,上面的代码可以大大改进。很多TrueFalse提示使用&&||代替。

作为提示,请尝试使用(some property of i) && (some property of j),如果您想简化代码。根据需要,属性可以包含==||。 (对于更高级的解决方案,请利用elem