0

我在理解函数组成和部分应用函数的概念时遇到了问题。

实际上,我正在编写一个小型光线追踪器,并有一些我不完全理解的示例实现。这是一个我不明白的例子(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其中foldr-part 表示部分应用的函数(当我是对的时候)。函数的概念很明确,就是要把可见光源的光加在曲面上的一点上。对于每个可见光源,都effectivelight映射了一个函数。我不明白的是foldr-function 的最后一个参数(.map effectivelight)和函数的完整构造。有人可以向我解释功能(部分)和功能的构造吗?也许人们可以以更直观的方式编写函数?

4

1 回答 1

4

最后一部分不是 foldr 的参数,而是函数组合......

让我们把它分开:

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

它的输出是一个颜色,并且

foldr (zipWith (+)) black . map effectivelight

因此,它lightsvisible是一个以输入为输入并输出颜色的函数。

由于中缀运算符比其他任何东西绑定得更紧密,这实际上是两个函数组合在一起(. map effectivelight即 - 不是 foldr 的参数)

foldr (zipWith (+)) black

map effectivelight

请注意,map effectivelight它将一个列表作为输入并给出一个作为输出。 lightvisible是一个数组,map effectivelight使用 修改列表中的每个元素,effectivelight其结果实际上是 foldr 中的第三个参数。

于 2014-01-01T17:16:43.397 回答