deh*_*ehq 5 haskell map fold function-composition
所以,让我们直截了当.
:t (map.foldr)
(map.foldr) :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
Run Code Online (Sandbox Code Playgroud)
什么是[[a1] - > a]?我真的想要理解这个构图,所以我这样做:
-- map.foldr
map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
map :: (a1 -> b1) -> [a1] -> [b1]
(.) :: (y -> w) -> (x -> y) -> x -> w
foldr :: (a -> b -> b) -> b -> [a] -> b
y = (a1 -> b1) w = ([a1] -> [b1])
x = (a -> b -> b) y = (b -> [a] -> b)
y = (a1 -> b1)
y = (b -> [a] -> b)
_________________________
Run Code Online (Sandbox Code Playgroud)
在这一点上会发生什么?谢谢!
Chr*_*lor 14
要回答这个问题,这是很好的回忆是什么foldr和map做.
两者中较为复杂的是foldr哪种类型
-- list to be folded
-- v
foldr :: (a -> b -> b) -> b -> [a] -> b
-- ^ ^
--folding function terminal value
Run Code Online (Sandbox Code Playgroud)
要折叠的列表实际上是一个conses链(:)和一个终端空列表:
1 : 2 : 3 : []
Run Code Online (Sandbox Code Playgroud)
动作foldr是分别用折叠函数和终值替换:和[]构造函数:
foldr (+) 0 (1 : 2 : 3 : []) == 1 + 2 + 3 + 0
Run Code Online (Sandbox Code Playgroud)
该map功能比较简单.考虑它的一种方法是获取函数和列表,并将函数应用于列表的每个参数:
map :: (a -> b) -> [a] -> [b]
-- ^ ^
-- function list
Run Code Online (Sandbox Code Playgroud)
但是,您也可以将其视为一个函数,并将其提升为一个对列表起作用的函数:
map :: (a -> b) -> ( [a] -> [b] )
-- ^ ^
-- function function on lists
Run Code Online (Sandbox Code Playgroud)
组成这两个函数意味着什么map . foldr?请注意,这只是一个接一个地应用这些功能 - 特别是
(map . foldr) f == map (foldr f)
Run Code Online (Sandbox Code Playgroud)
既然你foldr先申请,你必须将它应用于一个函数f :: a -> b -> b,然后你得到另一个函数:
foldr f :: b -> [a] -> b
-- ^ ^
--terminal val list to be folded
Run Code Online (Sandbox Code Playgroud)
现在你申请map,它提升了对列表采取行动的功能:
map (foldr f) :: [b] -> [[a] -> b]
-- ^ ^
--list of terminal vals functions that fold lists
Run Code Online (Sandbox Code Playgroud)
这种类型看起来很奇怪,但它是有效的.现在,不是单个终端值,而是给它一个终端值列表,然后返回折叠函数列表 - 每个终端值对应一个.
为了更清楚,我们可以查看(+)具有类型的特定函数
(+) :: Num a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)
如果我们将其替换为上面的等式,我们得到
(map . foldr) (+) :: Num a => [a] -> [[a] -> a]
-- ^ ^
-- list of terminal vals functions that fold lists
Run Code Online (Sandbox Code Playgroud)
如果我们现在将它应用于列表,[0, 1, 2]我们将获得三个函数的列表:
(map . foldr) (+) [0,1,2] :: Num a => [[a] -> a]
Run Code Online (Sandbox Code Playgroud)
我们可以使用这个map ($x)习惯用法将列表中的每个函数应用于特定的参数.它必须是一个数字列表,我会选择[3,4,5].仔细观察:
> map ($[3,4,5]) ((map.foldr) (+) [0,1,2])
[12, 13, 14]
Run Code Online (Sandbox Code Playgroud)
[3,4,5]使用(+)折叠功能将列表折叠三次,每次使用不同的终端值:
3 + 4 + 5 + 0 == 12
3 + 4 + 5 + 1 == 13
3 + 4 + 5 + 2 == 14
Run Code Online (Sandbox Code Playgroud)
当终值是0,我们只需得到值的总和:3 + 4 + 5 == 12.当终值时,1我们得到的值多于值(13)的总和,当终值为时,2我们得到的值比值的总和(14)多两倍.