如何映射函数以对列表中的列表进行操作? 以下是我正在尝试做的一个例子,但我只是问一般问题。提前谢谢!
现在,我正在尝试将一个函数映射到一个列表的每个列表上(由itrCol xs返回)。
evalChange xs = map change $ itrCol xs
其中itrCol返回列表列表,其中每个列表都是一列。
itrCol xs = [getCol x xs | x <- (take (width xs) (iterate (\x -> (x + 1)*1) 0))]
getCol列出列给定的列索引列表
getCol :: Int -> [t] -> [t]
并且改变是:
change [] = []
change [x] = [x]
change [x,y] = [x,y]
change (x:y:z:ws) | x == y && y == z = 0 : y*(-1) : 0 : change ws
change (x:xs) = x : change xs
答案 0 :(得分:12)
看看这个!
map :: (a -> b) -> [a] -> [b]
(map.map) :: (a -> b) -> [[a]] -> [[b]]
(map.map.map) :: (a -> b) -> [[[a]]] -> [[[b]]]
等
答案 1 :(得分:6)
可以使用currying和另一个map来调用。
map (map change) $ itrCol xs
要了解有关currying的更多信息,请查看chapter in Learn You A Haskell,这是Haskell的一本优秀的初学者书。
答案 2 :(得分:3)
map
(和fmap
更重要的是)本质上提升了一个函数来处理列表,给你一个新功能:(我添加了多余的parens以使其更清晰)
map :: (a -> b) -> ([a] -> [b])
如果您映射第二个函数([a] -> [b])
,您将获得一个适用于列表列表的函数:
evalChange xs = map (map change) $ itrCol xs
(如果这不是你想要的那么请澄清)
答案 3 :(得分:1)
map
的类型签名是:
map :: (a -> b) -> [a] -> [b]
change
的一个合理类型签名是:
change :: [Integer] -> [Integer]
现在map
期望从a
到b
的函数作为其第一个参数。如果我们为change
提供[Integer]
至[Integer]
,a = [Integer]
和b = [Integer]
的函数。
map change :: [[Integer]] -> [[Integer]]
现在,如果从iterCol xs
生成的列表理解提供[[Integer]]
,那么我们可以将其应用于map change
:
map change (itrCol xs) :: [[Integer]]
这一切对我来说都很好。它起作用,因为map
是多态的。如果你给它一个将A变为B的函数,那么它将返回一个函数,将列的A 转换为 B 列表。 A和B的含义并不重要:正如你在这里看到的,它们甚至可以自己列出!