2016-03-14 37 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)