繁体   English   中英

将 Function 应用于列表中的每个元素

[英]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 ,它分别将其参数传递给idrotate 1 ,然后将这些结果传递给zipWith m

这里使用Monad ic 风格,

import Control.Monad (ap)
m2 :: [[a]] -> [[a]]
m2 = zipWith m `ap` rotate 1

在这种情况下,这不太清楚; 您可以阅读它,因为m2将其参数传递给zipWith mrotate 1 ,然后将后者的结果提供给前者的结果

老实说,我更喜欢另一个答案,因为它避免了导入rotate并获得与tail. cycle tail. cycle

暂无
暂无

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

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