zipWith(++)任意数量的列表

时间:2014-02-26 07:34:14

标签: haskell

我必须用(++)压缩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

3 个答案:

答案 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的答案也有效,但如上所述,你的功能没有任何问题。