0

関数の構成と部分的に適用される関数の概念を理解するのに問題があります。

実際、私は小さなレイトレーサーを書いていて、正確に理解できないいくつかの実装例があります。これは私が理解していない1つの例です(https://github.com/ryanl/haskell-raytracer/blob/master/src/RayTracer.hs):それは光線の色を検出する関数です:

srdetectcolour' :: Scene -> Ray -> Maybe (Surface, Scalar) -> Colour
srdetectcolour' scene (Ray rx rv) (Just (s,d)) = zipWith (+) lightadded (surface_colour s)
where lightsvisible :: [Light]
      lightsvisible = lightsvisiblefrom intersectpoint scene
      lightadded :: Colour
      lightadded = (foldr (zipWith (+)) black . map effectivelight) lightsvisible
      effectivelight :: Light -> Colour
      effectivelight (v,c) = map (round . (*10000.0) . (/ (vector_sum ((intersectpoint - v) * (intersectpoint - v)))) . fromInteger) c
      intersectpoint = (rx + (mult d rv))

lightadded-partが部分的に適用された関数を表す(サブ)関数に興味がありますfoldr(私が正しい場合)。関数の概念は明確で、表面上の点に可視光源の光を追加したいと考えています。effectivelightすべての可視光源に対して、マップされた関数があります。私が理解していないのは、関数の最後のパラメーターfoldr( . map effectivelight ) と関数の完全な構造です。誰かが私に関数 (部分的に) と関数の構造を説明できますか? 関数をより直感的な方法で記述できるのではないでしょうか?

4

1 に答える 1

4

その最後の部分は、foldr へのパラメーターではなく、むしろ関数合成です....

これを分解しましょう:

lightadded :: Colour
lightadded = (foldr (zipWith (+)) black . map effectivelight) lightsvisible

この出力は Color であり、

foldr (zipWith (+)) black . map effectivelight

したがって、lightsvisible入力として受け取り、Color を出力する関数です。

中置演算子は何よりも密接に結合するため、これは実際には一緒に構成された 2 つの関数です (つまり. map effectivelight、foldr へのパラメーターではありません)。

foldr (zipWith (+)) black

map effectivelight

map effectivelightリストを入力として取り、リストを出力として与える ことに注意してください。lightvisibleは配列で、map effectivelightを使用してリスト内の各要素を変更しeffectivelightます。この結果は実際には、foldr の 3 番目のパラメータです。

于 2014-01-01T17:16:43.397 に答える