2009年8月2日日曜日

Haskellでレイトレーシング(第3回)〜型による分岐にはパターンマッチを用いる


今回は、パターンマッチを使った分岐について書きます。

Common Lispのコードでは、レイとSurfaceの交点を計算するときに、typecase関数を使ってSufaceの型によって処理を分岐させています。分岐用の関数を用意しなければなりません。
(defun intersect (s pr xr yr zr)
(funcall (typecase s (sphere #'sphere-intersect))
s pt xr yr zr))

(defun sphere-intersect (s pr xr yr zr)
...)
一方、Haskellではパターンマッチを使うことで、型による分岐を自然に表現することができます。
intersect :: Surface -> Point -> Double -> Double -> Double -> Maybe Point
intersect (Sphere _ r (Point cx cy cz)) (Point px py pz) xr yr zr =
let a = (sq xr) + (sq yr) + (sq zr)
b = 2 * ((px-cx)*xr + (py-cy)*yr + (pz-cz)*zr)
c = (sq (px-cx)) + (sq (py-cy)) + (sq (pz-cz)) - (sq r)
n = minroot a b c
in case n of
Just n -> Just (Point (px+xr*n) (py+yr*n) (pz+zr*n))
Nothing -> Nothing
今回はSphereのみですが、その他の型を追加した場合にはマッチさせるパターンを追記するだけです。

このように、Haskellでは引数のパターンによって分岐することができるのです。

次回は、「3.NilはMaybeモナドで表現する」について書きます。

■他の記事
Haskellでレイトレーシング(第1回)〜導入
Haskellでレイトレーシング(第2回)〜ループは使わない
Haskellでレイトレーシング(第3回)〜型による分岐にはパターンマッチを用いる
Haskellでレイトレーシング(第4回)〜NilはMaybeモナドで表現する
Haskellでレイトレーシング(第5回)〜タプルを返せる

0 件のコメント: