2010-12-01 25 views
2

我想在Haskell中實現一個函數,它將採用任意整數列表xs和整數k,並返回一組列表,其中包含k可能的位置。試圖改進haskell中處理列表的當前醜陋的一段代碼

例如,對於一個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。任何人都可以提出一些辦法來做比這些代碼聰明的辦法嗎?

感謝

回答

3

this question摘自:

ins x []  = [[x]] 
ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys] 
1

我真的很喜歡這個定義的清晰度:

ins x ys = zipWith (\pre post -> pre ++ [x] ++ post) (inits ys) (tails ys) 
1
ins x xs = zipWith (\ a b -> a ++ (x:b)) (inits xs) (tails xs) 

[編輯]呸,爲時已晚,luqui打我:-)

然而,這裏的一個版本,而不拉姆達:

ins x xs = zipWith (flip (++).(:) x) (tails xs) (inits xs) 
2

您可以使用箭頭,也:

import Control.Arrow 

ins x = inits &&& tails >>> second (map (x:)) >>> uncurry (zipWith (++)) 

隨着&&&(「扇出」),你給一個參數兩種功能,這給一對結果。您可以使用>>>(「然後」)切換正常的應用程序順序,從而允許從左向右的操作鏈。 second只適用於配對的第二部分。最後,你需要一個uncurry來重組結果,在一個函數中提供一對期望兩個單獨的參數。