Не входит в область действия: конструктор данных "Движение"

Я хочу сделать функцию, которая изменяет определенное значение в соответствии с переданной буквой. (Это в основном заданные направления: Восток, Запад....)

Код:

data Movement  = N Int | S Int | E Int | W Int deriving (Eq, Show)

step :: Movement -> (Int, Int) -> (Int, Int)
step (Movement x h) (y, z) 
    | x == N = (y, z+h)
    | x == S = (y, z-h)
    | x == W = (y-h, z)
    | x == E = (y+h, z)

Пример:

step (N 1) (239, 578) == (239, 579)
step (S 1) (240, 578) == (240, 577)
step (W 1) (239, 578) == (238, 578)
step (E 1) (239, 577) == (240, 577)
step (N 61) (239, 578) == (239,639)
step (N 2) (-4, 0) == (-4, 2)
step (E 1) (-4, 0) == (-3, 0)
step (S (-61)) (239, 578) == (239,639)

я продолжаю получать

Не входит в область действия: конструктор данных "Движение"

сообщение об ошибке.


person No_Name    schedule 14.01.2020    source источник


Ответы (1)


Movement — это тип, а не значение. Вы не можете использовать это в шаблонах.

Кроме того, N и другие конструкторы — это функции, и вы не можете == выполнять функции.

Вместо этого вам нужно использовать сопоставление с образцом и забыть о охранниках.

step :: Movement -> (Int, Int) -> (Int, Int)
step (N h) (y,z) = ...
step (S h) (y,z) = ...
step (W h) (y,z) = ...
step (E h) (y,z) = ...

В качестве альтернативы, рефакторинг вашего типа:

data Direction = N | S | E | W deriving (Eq, Show)
data Movement  = Movement Direction Int deriving (Eq, Show)

step :: Movement -> (Int, Int) -> (Int, Int)
step (Movement x h) (y,z) 
    | x == N = (y, z+h)
    | x == S = (y, z-h)
    | x == W = (y-h, z)
    | x == E = (y+h, z)

Теперь ваш код работает, так как Movement также является конструктором данных, а N и друзья больше не являются функциями. Я бы все же предпочел избегать охранников и использовать

step :: Movement -> (Int, Int) -> (Int, Int)
step (Movement N h) (y,z) = (y, z+h)
step (Movement S h) (y,z) = (y, z-h)
step (Movement W h) (y,z) = (y-h, z)
step (Movement E h) (y,z) = (y+h, z)
person chi    schedule 14.01.2020