10

如何映射函数以对列表中的列表进行操作?以下只是我试图做的一个例子,但我只是作为一个一般性问题提出。提前致谢!

现在,我正在尝试将一个函数 change 映射到一个列表的每个列表(由 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
4

4 回答 4

14

看一下这个!

map           :: (a -> b) ->   [a]   ->   [b]
(map.map)     :: (a -> b) ->  [[a]]  ->  [[b]]
(map.map.map) :: (a -> b) -> [[[a]]] -> [[[b]]]

等等

于 2012-10-06T19:31:43.233 回答
7

可以只使用柯里化和另一个调用映射。

map (map change) $ itrCol xs

要了解更多关于 currying 的信息,请查看Learn You A Haskell 中的那一章,这是一本很棒的 Haskell 初学者书籍。

于 2012-10-06T19:10:01.957 回答
3

mapfmap更重要的是)本质上提升了一个函数来处理列表,给你一个新的函数:(我添加了多余的括号以使其更清晰)

map :: (a -> b) -> ([a] -> [b])

如果您映射第二个函数([a] -> [b]),您将获得一个适用于列表列表的函数:

evalChange xs = map (map change) $ itrCol xs

(如果这不是您想要的,请澄清)

于 2012-10-06T19:10:20.203 回答
1

的类型签名map是:

map :: (a -> b) -> [a] -> [b]

一种合理的类型签名change是:

change :: [Integer] -> [Integer]

现在map期望一个函数 from atob作为它的第一个参数。如果我们给它change一个函数 from [Integer]to [Integer], then a = [Integer]and b = [Integer]

map change :: [[Integer]] -> [[Integer]]

iterCol xs现在,如果从提供 a生成的列表理解[[Integer]],那么我们可以将其应用于map change

map change (itrCol xs) :: [[Integer]]

这一切对我来说都很好。它之所以有效,是因为它map是多态的。如果你给它一个把 A 变成 B 的函数,那么它会给你一个把A 的列表变成B的列表的函数。A 和 B 是什么并不重要:正如您在此处看到的,它们甚至可以是列表本身!

于 2012-10-06T22:44:24.727 回答