[英]Apply map using a different function to each element of the list
I currently have this bit of code: 我目前有这段代码:
function string keys = map (xor 1) (map ord string)
Which takes every element from the string and xor's it with 1. I would like to make the map function more advanced, by replacing 1 with any element from keys. 它从字符串中获取每个元素,然后用1对其进行异或运算。我想通过将键1中的任何元素替换为1来使map函数更高级。
So for example if string == "Test"
and keys = [1,3,6,9]
I would get: 因此,例如,如果string == "Test"
且keys = [1,3,6,9]
我将得到:
'T' xor 1
'e' xor 3
's' xor 6
't' xor 9
Is there a way to iterate over all element of keys so that I can achieve this? 有没有办法遍历键的所有元素以便我可以实现这一点? I'm pretty new to Haskell and I don't have a good grasp of its concepts. 我对Haskell还是很陌生,对它的概念也不太了解。
My attempt at solving this was: 我解决这个问题的尝试是:
function string keys = map (iterate xor keys) (map ord string)
but I got a few errors and I guess it's because of the iterate function. 但是我遇到了一些错误,我猜这是由于迭代功能造成的。
Any help would be greatly appreciated! 任何帮助将不胜感激!
Just as I posted I noticed that iterate does a completely different thing so at this point I know why it doesn't work but I don't know how to replace it. 就像我发布的那样,我注意到iterate做的事情完全不同,所以在这一点上我知道为什么它不起作用,但是我不知道如何替换它。
You want to associate one element of a list with one element of the other list. 您想要将一个列表的一个元素与另一个列表的一个元素相关联。 This is often called zipping . 这通常称为zipping 。 The zipWith
seems to do exactly what you want: zipWith
似乎完全zipWith
您的要求:
Prelude Data.Bits> zipWith xor [1, 3, 5] [10, 23, 44]
[11,20,41]
It takes an a -> b -> c
function, an [a]
list and a [b]
list and apply the function element wise with corresponding elements from the two lists. 它需要a -> b -> c
函数,一个[a]
列表和一个[b]
列表,并将该功能元素与两个列表中的相应元素一起明智地应用。
It is a generalization of the zip
function that produces pairs of element ( zip = zipWith (,)
). 这是zip
函数的通用化,它会生成成对的元素( zip = zipWith (,)
)。
That's what the ZipList
instance of type class Applicative
is doing: 这就是类型类Applicative
的ZipList
实例正在做的事情:
> getZipList $ xor . ord <$> ZipList "Test" <*> ZipList [1,3,6,9, 11]
[85,102,117,125]
The get/ZipList
s serve as kind of markers to signal our intent to zip, instead of the regular list's cross-product behaviour. get/ZipList
用作一种标记,表示我们打算压缩,而不是常规列表的跨产品行为。 We're supposed to pretend--"ignore" them, reading it in our minds instead as 我们应该假装-“忽略”它们,在我们的脑海中阅读它,而不是
-- zipWith ( xor . ord ) "Test" [1,3,6,9, 11]
which is the same as 这与
-- zipWith xor (map ord "Test" ) [1,3,6,9, 11]
-- zipWith ($) (map (xor . ord) "Test" ) [1,3,6,9, 11]
-- map (uncurry ($)) (zip (map (xor . ord) "Test" ) [1,3,6,9, 11] )
-- map (\(a,b)-> xor (ord a) b) (zip "Test" [1,3,6,9, 11] )
<$>
is a synonym for fmap
which is a synonym for map
, and <*>
is "apply". <$>
是fmap
的同义词, fmap
是map
的同义词,而<*>
是“ apply”。
Without the ZipList
marker, we get 没有ZipList
标记,我们得到
> [ord] <*> "Test"
[84,101,115,116]
-- ord <$> "Test"
-- map ord "Test"
Specifically, your code should be tweaked a little bit into 具体来说,您的代码应进行一些调整
function :: [Char] -> [Int] -> [Int]
-- function string keys = map (iterate xor keys) (map ord string)
function string keys = zipWith ($) (map xor keys) (map ord string)
-- = getZipList $ (xor <$> ZipList keys) <*> (ord <$> ZipList string)
($)
is an application operator, ($) fx = f $ x = fx
. ($)
是应用程序运算符, ($) fx = f $ x = fx
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.