如何在Haskell中将两个列表与高阶函数交织在一行中

时间:2014-03-28 00:37:21

标签: haskell

我想获取两个列表并使用一行代码返回交错列表。

interleave :: [a] -> [a] -> [a]
interleave xs ys = concat (zipWith (:) xs ys) 

不确定为什么这不起作用。

知道了:

interleave :: [a] -> [a] -> [a]
interleave xs ys = concat (zipWith (\x y -> [x]++[y]) xs ys)

5 个答案:

答案 0 :(得分:6)

你可能也喜欢

interleave xs ys = concat (transpose [xs, ys])

这是基于我很久以前读过的观察(我现在无法记住 - 也许在Python文档中)转换只是一个n路拉链。

答案 1 :(得分:1)

我真的很喜欢这个页面与haskell中的函数的机制一起玩(让你的大脑也开始)

http://www.haskell.org/haskellwiki/Pointfree

其中一个例子是:

pl \(a,b) -> a:b:[]  
uncurry ((. return) . (:))

所以你也可以这样做:

[ghci] ((. return) . (:)) 1 2
[1,2]
[ghci] concat $ zipWith ((. return) . (:)) [1..10] [11..20]
[1,11,2,12,3,13,4,14,5,15,6,16,7,17,8,18,9,19,10,20]
但是,丹尼尔瓦格纳的表现要干净得多:)

答案 2 :(得分:1)

Codegolf!

以下是如何交错两个相同长度的列表(截断两个列表中较长的列表,因为所有基于zipWith的解决方案都有):

f = (foldr($)[].).zipWith((.(:)).(.).(:))

答案 3 :(得分:0)

你需要的函数是(\a b-> a:b:[])这是微不足道的,我怀疑Haskell中有明确提供的东西可以做到这一点。你总是可以定义自己的......

[ghci] let (#) a b = [a,b]
[ghci] 3 # 4
[3,4]
[ghci] concat  ( zipWith (#) [1,2,3] [5,6,7] )
[1,5,2,6,3,7]
[ghci] 

答案 4 :(得分:0)

你想要interleave xs ys = concatMap (\(x, y)->[x, y]) (zipWith (,) xs ys)zipWith子表达式将两个列表转换为[(x0, y0), (x1, y1)]元组列表,concatMap将它们转换为列表。