简体   繁体   English

Haskell:将函数映射到列表列表

[英]Haskell: Map function onto a list of lists

How do you map a function to operate on lists within a list? 您如何映射功能以对列表中的列表进行操作? The following is just what I'm trying to do as an example, but I was just asking as a general question. 以下仅是我想做的一个例子,但我只是在问一个一般性的问题。 Thanks in advance! 提前致谢!

Right now, I'm trying to map a function, change, onto each lists of one list (returned by itrCol xs). 现在,我正在尝试将一个函数(变化)映射到一个列表的每个列表上(由itrCol xs返回)。

evalChange xs = map change $ itrCol xs

where itrCol returns a list of lists, where each containing list is a column. 其中itrCol返回列表列表,其中每个包含列表的列均为一列。

itrCol xs = [getCol x xs | x <- (take (width xs) (iterate (\x -> (x + 1)*1) 0))]

getCol lists column given list of column indices getCol列出了给定的列索引列表的列

getCol :: Int -> [t] -> [t]

and change is: 更改是:

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

Check this out! 看一下这个!

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

etc. 等等

Could just use currying and another call to map. 可以只使用currying和另一个调用来映射。

map (map change) $ itrCol xs

To learn more about currying take a look at that chapter in Learn You A Haskell , a great beginner book in Haskell. 要了解有关currying的更多信息,请参阅Haskell的入门入门书籍Learn You A Haskell中的这一

map (and fmap more importantly) essentially lifts a function to work on lists, giving you a new function: (I added superfluous parens to make it more clear) map (更重要的是fmap )本质上提升了一个在列表上工作的功能,从而为您提供了一个新功能:(我添加了多余的括号以使其更加清楚)

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

If you map that second function ([a] -> [b]) you will get a function that works on lists of lists: 如果您映射第二个函数([a] -> [b])您将获得一个适用于列表列表的函数:

evalChange xs = map (map change) $ itrCol xs

(if this is not what you wanted then please clarify) (如果这不是您想要的,请澄清)

The type signature of map is: map的类型签名为:

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

One sensible type signature for change is: 进行change一个明智的类型签名是:

change :: [Integer] -> [Integer]

Now map expects a function from a to b as its first argument. 现在map期望一个从ab的函数作为其第一个参数。 If we give it change , a function from [Integer] to [Integer] , then a = [Integer] and b = [Integer] . 如果我们给它change ,则函数从[Integer][Integer] ,则a = [Integer]b = [Integer]

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

Now if that list comprehension produced from iterCol xs supplies a [[Integer]] , then we can apply that to map change : 现在,如果从iterCol xs产生的列表理解提供了[[Integer]] ,那么我们可以将其应用于map change

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

This all looks fine to me. 这一切对我来说都很好。 It works because map is polymorphic. 之所以起作用,是因为map是多态的。 If you give it a function that turns A into B, then it will give you back a function that turns lists of A into lists of B . 如果您给它一个将A变成B的函数,那么它将给您一个将A的 列表变成B的函数。 It doesn't matter what A and B are: as you can see here, they can even be lists themselves! 不管A和B是什么:正如您在此处看到的那样,它们甚至可以自己列出!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM