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
多くのブラケットを使用しない方法はありますか?
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
多くのブラケットを使用しない方法はありますか?
コードを簡素化できる場所を特定するには、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 座標を抽出することもできますが、この場合、コードが煩雑になる可能性があります。
Double
また、Haskellでは、一般的にFloat
.
アクセサーを定義することにより、関数内で線と点を分離できますが、括弧なしでパターン マッチングを行う方法はありません。
括弧を取り除く別の方法は、多くのケース式でパターン マッチングを行うことです。
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
これは、コンパイラがパターンマッチを「変換」するものに近いですが、もちろん、これはあまり改善されていません!
ただし、同じカスケード パターン マッチングに変換されるこの式の記述方法は多数あります。ここに1つあります:
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
私の意見では、最後のものはかなり素晴らしく読みやすいですが、他の提案はより良い構造化プログラムにつながるため、はるかに優れています!
(反論の余地のないパターンについては、私が詳しく説明しているものがありますが、これは単一コンストラクターのデータ型でのみ機能します)