Ошибка с функцией подачи квадранта

Я попытался сделать функцию, чтобы дать имя квадранта при вводе координат х и у. Тем не менее, я получаю сообщение об ошибке: "Ошибка разбора на входе '='

Не удалось, модули загружены: нет. "

Я попытался добавить "| иначе..", но это все равно не сработало. Я удостоверился, что покрыл все возможности x и y.

data Quadrants = Origin |
                 Quadrant_I | Quadrant_II | Quadrant_III | Quadrant_IV |
                 X_Axis_Positive | X_Axis_Negative | Y_Axis_Positive | Y_Axis_Negative
  deriving (Show, Eq)
quadrant :: Float -> Float -> Quadrants
quadrant x y
    |x>0 && y>0 = Quadrant_I
    |x<0 && y>0 = Quadrant_II
    |x<0 && y<0 = Quadrant_III
    |x>0 && y<0 = Quadrant_IV
    |x=0 && y=0 = Origin
    |x>0 && y=0 = X_Axis_Positive
    |x<0 && y=0 = X_Axis_Negative
    |x=0 && y>0 = Y_Axis_Positive
    |x=0 && y<0 = Y_Axis_Negative

3 ответа

x=0

= используется в качестве ключевого слова для определений. Поскольку вы не можете (и не хотите) определить x быть 0 в этот момент вы получаете ошибку синтаксического анализа. То, что вы ищете, это функция сравнения. В Хаскеле это ==, увидеть Data.Eq,

Я думаю, что вы можете упростить структуру, если вы разъедините знак каждой координаты в качестве другого типа и сопоставления с образцом в промежуточном типе, т.е.

data Sign = Negative | Zero | Positive
sign x | x==0 = Zero
       | x>0  = Positive
       | otherwise = Negative

а потом

quadrant :: Float -> Float -> Quadrants
quadrant x y = go (sign x) (sign y)
       where go Zero Zero = Origin
                Zero Positive = Y_Axis_Positive
                ...

Или вы можете исключить необходимость использования типа Quadrants, и вместо этого вы можете использовать кортеж (Sign, Sign), который может быть более полезен для следующих шагов.

Это в основном дубликат очень хорошего ответа karakfa, просто чтобы указать, что Haskell поставляется с типом данных, который изоморфен Signа именно Ordering,

quadrant :: Float -> Float -> Quadrants
quadrant x y = go (compare x 0) (compare 0 y)
               where go EQ EQ = Origin
                     go EQ GT = Y_Axis_Positive
                     go EQ LT = Y_Axis_Negative
            ...

Ваш Quadrants тип просто изоморфен парам Ordering значения, что означает, что вы могли бы написать код, как

type Quadrant = (Ordering, Ordering)
origin = (EQ, EQ)
quadrant_i = (GT, GT)
-- etc

quadrant :: Float -> Float -> Quadrant
quadrant x y = ((compare x 0), (compare y 0))

Это имеет недостаток в том, что требуется расширение языка для сопоставления с шаблоном, скажем, origin скорее, чем (EQ, EQ) непосредственно.

Другие вопросы по тегам