我正在尝试在Haskell中实现一个函数,该函数将采用任意整数列表xs
和整数k
,并在所有可能的位置返回一组带有k
的列表
例如,对于xs = [0, 1]
和k = 2
,我们有
myFunction [0, 1] 2 = [ [2, 0, 1], [0, 2, 1], [0, 1, 2] ]
我已将其实现为
putOn xs x i = (take i xs) ++ (x:(drop i xs))
putOnAll xs x = map (putOn xs x) [0..(length xs)]
然而,我觉得必须有其他更聪明的方法来实现同样的目标。我的代码似乎有人试图用导弹杀死一个bug。任何人都可以在做一些聪明的事情而不是这些代码吗?
由于
答案 0 :(得分:3)
ins x [] = [[x]]
ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys]
答案 1 :(得分:3)
您也可以使用箭头:
import Control.Arrow
ins x = inits &&& tails >>> second (map (x:)) >>> uncurry (zipWith (++))
使用&&&
(“扇出”),您可以为两个函数提供一个参数,从而得到一对结果。您可以使用>>>
(“然后”)来切换正常的应用程序顺序,从而允许从左到右的操作链。 second
仅适用于该对的第二部分。最后,您需要uncurry
来重新组合结果,在函数中提供一对期望两个单独的参数。
答案 2 :(得分:1)
我真的很喜欢这个定义的清晰度:
ins x ys = zipWith (\pre post -> pre ++ [x] ++ post) (inits ys) (tails ys)
答案 3 :(得分:1)
ins x xs = zipWith (\ a b -> a ++ (x:b)) (inits xs) (tails xs)
[编辑]巴,太迟了,luqui打败了我: - )
但是,这里没有lambda的版本:
ins x xs = zipWith (flip (++).(:) x) (tails xs) (inits xs)