![](/img/trans.png)
[英]Apply a function to every element in a list to every element in another list - Haskell
[英]Apply a Function to every element in a list
我创建了一个 function m
这样
m "abc" "def" == "bcd"
我想创建另一个 function 使用m
生成 output ["bcd","efg","hia"]
当给定输入["abc","def","ghi"]
m
的定义是
m :: [a] -> [a] -> [a]
m str1 str2 = (drop 1 str1) ++ (take 1 str2)
您可以在此处使用zipWith:: (a -> b -> c) -> [a] -> [b] -> [c]
将整个列表作为第一个参数,并将tail (cycle l)
作为第二个参数(与l
列表):
combine :: [a] -> [a]
combine l = zipWith m l (tail (cycle l))
zipWith
将同时枚举两个列表,并且每次调用m
时使用第一个和第二个列表的元素。 例如:
Prelude> combine ["abc","def","ghi"]
["bcd","efg","hia"]
您可以 append 将第一个元素到末尾来模拟一个环绕,然后zip 列表及其尾部以获取每个元素的元组,然后map
它:
f :: [[a]] -> [[a]]
f [] = []
f l@(x:xs) = map (\(a, b) -> m a b) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
或者,您可以使用uncurry
:
f :: [[a]] -> [[a]]
f [] = []
f l@(x:xs) = map (uncurry m) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
import Data.List.HT (rotate)
m2 :: [[a]] -> [[a]]
m2 list = zipWith m list (rotate 1 list)
其中m
是你的。
你可以通过几种方式让它变得免费。
这里使用Applicative
样式,
m2 :: [[a]] -> [[a]]
m2 = zipWith m <$> id <*> (rotate 1)
可以读作m2
是 function ,它分别将其参数传递给id
和rotate 1
,然后将这些结果传递给zipWith m
。
这里使用Monad
ic 风格,
import Control.Monad (ap)
m2 :: [[a]] -> [[a]]
m2 = zipWith m `ap` rotate 1
在这种情况下,这不太清楚; 您可以阅读它,因为m2
将其参数传递给zipWith m
和rotate 1
,然后将后者的结果提供给前者的结果。
老实说,我更喜欢另一个答案,因为它避免了导入rotate
并获得与tail. cycle
tail. cycle
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.