data Point = Point Float Float deriving (Show)
data Line = Line Point Point deriving (Show)
onLine :: Line -> Point -> Bool
onLine (Line (Point x1 y1) (Point x2 y2)) (Point x y) = True
有沒有辦法不使用這麼多的括號?Haskell代碼中是否需要括號
data Point = Point Float Float deriving (Show)
data Line = Line Point Point deriving (Show)
onLine :: Line -> Point -> Bool
onLine (Line (Point x1 y1) (Point x2 y2)) (Point x y) = True
有沒有辦法不使用這麼多的括號?Haskell代碼中是否需要括號
我推薦一個名爲hlint的工具來識別可以簡化代碼的地方。
在您的代碼/書面/,你不使用的值x1
,y1
,x2
,y2
,x
或y
,所以你可以這樣寫:
onLine _ _ = True
不過,我認爲這只是一個存根,實際上你會用變量做一些事情。一般來說,如果您確實需要引用所有這些變量,那麼您需要按照您所做的方式編寫它。但是,也許你正在使用一個只需要整行值的幫助函數。然後,你可以寫這樣的:
onLine l p = blah blah blah
-- use slope l and yIntercept l to figure out if p is on the line
slope :: Line -> Float
slope (Line (Point x1 y1) (Point x2 y2)) = (y2 - y1)/(x2 - x1)
yIntercept :: Line -> Float
yIntercept (Line (Point x1 y1) (Point x2 y2)) = blah blah blah
或者,你可以只使用訪問函數來提取點和線的X和Y座標,但在這種情況下,它可能使你的代碼混亂。
另外,在Haskell中,我認爲使用Double
而不是Float
通常更有效。
您可以通過定義訪問器來取消函數中的直線和點,但是如果沒有括號,則無法進行模式匹配。
有時可以使用記錄符號避免使用括號,有時使用$
,有時使用中綴函數,有時如果不是過多,也可以。
讓我們使用記錄表示法獲得座標的大量訪問權限,但我們將僅保留Line
。
data Point = Point {x::Double,y::Double} deriving (Show)
data Line = Line Point Point deriving (Show)
這定義了x :: Point -> Double
和y :: Point -> Double
。
有作爲浮點平等沒有這樣的事情,但我還是要大致右:
accuracy = 0.000000000001
is :: Double -> Double -> Bool
is x y = abs (x - y) < accuracy
我可以用這個作爲x point1 `is` x point2
整齊地避免了括號is (x point1) (x point2)
當你的數據結構沒有如此嚴重地與模式匹配嵌套,幾個括號易於閱讀:
gradient :: Line -> Double
gradient (Line one two) = (y two - y one)/(x two - x one)
但是,我們可以去一個更深的機智由於功能x
和y
,使用過多的方括號。
asFunction :: Line -> (Double -> Double) -- () for clarity, not necessity
asFunction [email protected](Line point _) = \xx -> gradient l * (xx - x point) + y point
通知我用[email protected]
引入一個別名(Line point _)
節省打字的權利。
現在我們可以使用中綴函數招擺脫幾個括號:
onLine :: Line -> Point -> Bool
onLine l p = l `asFunction` x p `is` y p
在右手邊,你可以使用$
來擺脫括號,但你不能使用它在模式匹配的左邊,因爲它是一個函數f $ x = f x
。例如
this (that (the other thing (something other)))
= this $ that $ the other thing $ something other
= this . that . the other thing $ something other
謝謝@leftaroundabout。這確實是我的意圖。 – AndrewC
擺脫括號的另一種方式是做模式匹配在一些情況下的表達式:
onLine l p = case l of
Line p1 p2 -> case p1 of
Point x1 y1 -> case p2 of
Point x2 y2 -> case p of
Point x y -> True -- you can use x1,y1,x2,y2,x and y here
這是緊挨什麼編譯器「翻譯」的patternmatches到,但這當然不是一個很大的改進!
但是,有很多寫這個表達式的方法,也是轉換爲相同的級聯模式匹配;這裏有一個:
onLine l p = let
Line (Point x1 y1) (Point x2 y2) = l
Point x y = p
in True
和這裏的另一個:
onLine l p = True where
Line (Point x1 y1) (Point x2 y2) = l
Point x y = p
最後一個是相當不錯的,可讀性,在我看來,但其他建議要好得多,因爲他們會帶來更好的結構化程序!
(有關於我粉飾無可辯駁的模式,單構造數據類型這僅適用於一些東西)
你可以刪除'Show'獲得子句周圍括號。你無能爲力;畢竟,你如何將對手模式彼此分開而不用花括號? –