Lea*_*nan 3 haskell filtering map
完全是Haskell的新手,通过Learn Haskell学习更大的好处.
我正在看地图功能
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
Run Code Online (Sandbox Code Playgroud)
是否可以为此添加谓词?例如,仅映射到列表中的每个其他元素?
您可以将自己的版本编码map为f仅应用于偶数(或奇数)位置,如下所示.(指数从下方开始0)
mapEven :: (a->a) -> [a] -> [a]
mapEven f [] = []
mapEven f (x:xs) = f x : mapOdd f xs
mapOdd :: (a->a) -> [a] -> [a]
mapOdd f [] = []
mapOdd f (x:xs) = x : mapEven f xs
Run Code Online (Sandbox Code Playgroud)
如果你想要利用库函数,你可以做类似的事情
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (\(flag,x) -> if flag then f x else x) . zip (cycle [True,False])
Run Code Online (Sandbox Code Playgroud)
甚至
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (uncurry (\flag -> if flag then f else id)) . zip (cycle [True,False])
Run Code Online (Sandbox Code Playgroud)
如果要使用索引上的任意谓词进行过滤,则:
mapPred :: (Int -> Bool) -> (a->a) -> [a] -> [a]
mapPred p f = map (\(i,x) -> if p i then f x else x) . zip [0..]
Run Code Online (Sandbox Code Playgroud)
使用zipWith(如@amalloy建议的)可以达到更直接的解决方案.
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith (\flag x -> if flag then f x else x) (cycle [True,False])
Run Code Online (Sandbox Code Playgroud)
这可以进一步细化如下
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith ($) (cycle [f,id])
Run Code Online (Sandbox Code Playgroud)