需要帮助理解 Haskell id 函数
Need help understanding Haskell id function
你好,我有这个函数的两个版本,我遇到了一些问题。
iter :: Int -> (a -> a) -> (a -> a)
iter n f
| n > 0 = f . iter (n-1) f
| otherwise = id
iter' :: Int -> (a -> a) -> (a -> a)
iter' n = foldr (.) id . replicate n
即使在谷歌上搜索 id 在这里实际做了什么,我也无法理解。
例如,如果我们使用 n = 3
和 f x = x+1
来处理函数。
当我们遍历整个 n
并到达调用 id
时,我们的变量会发生什么?
我是个大新手,能不能解释的简单点。
您可以内联:
iter 3 f
f . iter 2 f
f . (f . iter 1 f)
f . (f . (f . iter 0 f)
f . (f . (f . id))
-- adding the argument x
iter 3 f x
(f . (f . (f . id))) x
-- using (g . h) x == g (h x)
f ((f . (f . id)) x)
f (f ((f . id) x))
f (f (f (id x)))
f (f (f x))
而在 iter'
的情况下:
iter' 3 f
(foldr (.) id . replicate 3) f
foldr (.) id (replicate 3 f)
foldr (.) id [f, f, f]
(.) f (foldr (.) id [f, f]]
(.) f ((.) f (foldr (.) id [f]))
(.) f ((.) f ((.) f (foldr (.) id [])))
(.) f ((.) f ((.) f id))
f . (f . (f . id))
对列表求和xs = [x1,x2,...,xn]
可以可视化为
x1 + x2 + ... + xn + 0
请注意最后的 + 0
。它的目的是处理列表为空的情况,即 xs = []
和 n=0
。在这种情况下,上面的总和减少到 0
,这是空列表的正确总和。
另请注意,当列表不为空时,额外的 + 0
对总和没有影响,因此是无害的。我们确实选择 0
因为它是加法的中性元素: x + 0 = x
对所有 x
.
如果我们想计算一个产品,我们会写
x1 * x2 * ... * xn * 1
注意最后是* 1
。它的作用和上面看到的+ 0
完全一样。另请注意,1
是乘法的中性元素:x * 1 = x
对所有 x
.
如果我们想计算函数列表的组成,我们会写
f1 . f2 . ... . fn . id
注意最后是. id
。它的作用和上面看到的+ 0
和* 1
完全一样。另请注意,id
是所有 f
.
组合 f . id = f
的中性元素
希望这会帮助您理解为什么,每次我们计算一个折叠
x1 op x2 op ... op xn
其中 op
是任何二元运算,我们希望以 ... op neutral_element
结束,以便处理空列表情况,并且仍然作为非空列表的良好基本情况。
你好,我有这个函数的两个版本,我遇到了一些问题。
iter :: Int -> (a -> a) -> (a -> a)
iter n f
| n > 0 = f . iter (n-1) f
| otherwise = id
iter' :: Int -> (a -> a) -> (a -> a)
iter' n = foldr (.) id . replicate n
即使在谷歌上搜索 id 在这里实际做了什么,我也无法理解。
例如,如果我们使用 n = 3
和 f x = x+1
来处理函数。
当我们遍历整个 n
并到达调用 id
时,我们的变量会发生什么?
我是个大新手,能不能解释的简单点。
您可以内联:
iter 3 f
f . iter 2 f
f . (f . iter 1 f)
f . (f . (f . iter 0 f)
f . (f . (f . id))
-- adding the argument x
iter 3 f x
(f . (f . (f . id))) x
-- using (g . h) x == g (h x)
f ((f . (f . id)) x)
f (f ((f . id) x))
f (f (f (id x)))
f (f (f x))
而在 iter'
的情况下:
iter' 3 f
(foldr (.) id . replicate 3) f
foldr (.) id (replicate 3 f)
foldr (.) id [f, f, f]
(.) f (foldr (.) id [f, f]]
(.) f ((.) f (foldr (.) id [f]))
(.) f ((.) f ((.) f (foldr (.) id [])))
(.) f ((.) f ((.) f id))
f . (f . (f . id))
对列表求和xs = [x1,x2,...,xn]
可以可视化为
x1 + x2 + ... + xn + 0
请注意最后的 + 0
。它的目的是处理列表为空的情况,即 xs = []
和 n=0
。在这种情况下,上面的总和减少到 0
,这是空列表的正确总和。
另请注意,当列表不为空时,额外的 + 0
对总和没有影响,因此是无害的。我们确实选择 0
因为它是加法的中性元素: x + 0 = x
对所有 x
.
如果我们想计算一个产品,我们会写
x1 * x2 * ... * xn * 1
注意最后是* 1
。它的作用和上面看到的+ 0
完全一样。另请注意,1
是乘法的中性元素:x * 1 = x
对所有 x
.
如果我们想计算函数列表的组成,我们会写
f1 . f2 . ... . fn . id
注意最后是. id
。它的作用和上面看到的+ 0
和* 1
完全一样。另请注意,id
是所有 f
.
f . id = f
的中性元素
希望这会帮助您理解为什么,每次我们计算一个折叠
x1 op x2 op ... op xn
其中 op
是任何二元运算,我们希望以 ... op neutral_element
结束,以便处理空列表情况,并且仍然作为非空列表的良好基本情况。