2016-03-14 38 views
0

我试图在输入x和y坐标时使函数给出象限名称。但是,我收到错误: “输入解析错误”='象限给出函数的错误

失败,模块加载:无。“

我试着添加一个“|否则......”但仍然没有工作。我确信我涵盖了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 

回答

4
x=0 

=用作keyword for definitions。由于您目前无法(也不想)将x定义为0,因此会出现解析错误。你要找的是比较功能。在Haskell中,这是==,请参阅Data.Eq

1

我觉得如果你去耦的每一个坐标作为中介类型其他类型和模式匹配的标志可以简化结构,即

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),这对于后续步骤可能更有用。

+0

您可以使用'compare 0'来代替'sign',并在结果'Ordering'值上进行模式匹配。 – chepner

0

这主要是卡拉克非常好的答案的重复,只是为了指出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)