Haskellで書いたコードはこれで、実行すると以下のようなpgm画像が得られます。
Common LispのコードをHaskellで書くにあたっては、次のようなところがポイントでした。
1.ループを使わない
Common Lispのコードでは、各ピクセルごとに手続き的にループを回すようになっていますが、Haskellではそれをループを使わずに記述します。どのように書くのかというと、全ピクセルをリストで表現し、それを関数に渡すのです。Haskellの遅延評価が活きてくるポイントです。2.型による分岐にはパターンマッチを用いる
Common Lispのコードでは、物体の型を判別して処理を分岐しています。Haskellでは、引数のパターンマッチでこれをもっと自然に表現できます。3.NilをMaybeモナドで表現する
レイが物体と衝突しない場合に、Commpn Lispのコードでは暗黙的にNilを返すように記述されています。それを、Maybeモナドを使いNothingで表現するようにしました。レイが物体に衝突するときにはその交点を返し、衝突しないときにはNothingを返します。4.タプルを返せる
Common Lispのコードではmultiple-value-bindを使って値の組を返す部分があります。Haskellではそのままタプルを返すことができます。5.衝突点の計算
Common Lispのコードでは、もっとも視点に近い衝突点を探すためにループが用いられています。Haskellでは、この衝突点の計算もループを使わずに表現します。foldrを使って、Haskellらしい形で表現しました。次回以降の投稿で、これらのポイントを1つずつ説明していきます。
■他の記事
Haskellでレイトレーシング(第1回)〜導入
Haskellでレイトレーシング(第2回)〜ループは使わない
Haskellでレイトレーシング(第3回)〜型による分岐にはパターンマッチを用いる
Haskellでレイトレーシング(第4回)〜NilはMaybeモナドで表現する
Haskellでレイトレーシング(第5回)〜タプルを返せる