我必须用(++)压缩n个列表。我发现在列表上定义此运算符没有更好的方法:
(+++) = zipWith (\x y -> x ++ " " ++ y)
有更好的解决方案吗?
在Markus1189回答之后,我提出了一个更一般的问题:确实存在这样的函数:
zipNWith f2 [a] = f2 (f2 x1 x2) x3 ... f2 (xn-2 xn-1) xn?
这是使用运算符(+++)
的程序csoundLines instrs inits durs amps freqs = putStrLn . unlines $
repeat "i" +++ ms instrs +++ ms inits +++ ms durs +++ ms amps +++ ms freqs
where
(+++) = zipWith (\x y -> x ++ " " ++ y)
ms xs = map show xs
scaleNTonic n = map (\i -> 440 * 2 ** (i/n)) [0..n]
- 示例:csoundLines(重复1)[0.5,1 ...](重复0.5)(重复0.3)$ scaleNTonic 6
> i 1 0.5 0.5 0.3 440.0
> i 1 1.0 0.5 0.3 493.8833012561241
> i 1 1.5 0.5 0.3 554.3652619537442
> i 1 2.0 0.5 0.3 622.2539674441618
> i 1 2.5 0.5 0.3 698.4564628660078
> i 1 3.0 0.5 0.3 783.9908719634985
> i 1 3.5 0.5 0.3 880.0
答案 0 :(得分:5)
处理任意数量的列表的最简单方法是将它们全部放在列表中:
import Data.List
zipAll :: [[String]] -> [String]
zipAll = map unwords . transpose
ghci> zipAll [["a", "b", "c"], ["1", "2", "3"], ["xx", "yy", "zz"]]
["a 1 xx","b 2 yy","c 3 zz"]
我不确定是否有一种简单的方法可以将它们作为单独的参数传递(数字未定义),但您可以使用printf的方法。
答案 1 :(得分:5)
你也可以使用折叠来获得任意数量的列表:
>>> foldr1 (zipWith (++)) [["dog","cat"],["cat","dog"],["rat","rat"]]
["dogcatrat","catdograt"]
或者中间有空格:
>>> foldr1 (zipWith (\x y -> x ++ " " ++ y)) [["dog","cat"],["cat","dog"],["rat","rat"]]
["dog cat rat","cat dog rat"]
答案 2 :(得分:0)
IMO你的方法没有错。如果一个人真的关心性能,我会稍微改变一下:
(+++) = zipWith (\x y -> x ++ (' ' : y))
以便您避开" " ++ <long list>
。
还有ZipList,但你必须传递一个函数来获取你给它的确切数量的参数,我想这不是你想要的。 Yuuri的答案也有效,但如上所述,你的功能没有任何问题。