2013-03-30 100 views
2

我在尋找實現此功能的方法:這些功能函數叫什麼?

list = [a b c d e f] 
foo(list, 3) = [[a d] [b e] [c f]] 

一個潛在的解決方案是:

foo(list,spacing) = zip(goo(list,spacing)) 

其中,例如,

goo([a b c d e f],3) = [[a b c] [d e f]] 

什麼是foogoo通常被稱爲,所以我可以尋找現有的解決方案,而不是重新發明輪子?

備註:我沒有試圖用文字解釋,而是展示了希望更容易獲得的例子。用於更廣泛理解的任意語法。

+0

我認爲你正在尋找的術語是「高階函數」或「組合子」。 –

+0

在第一個例子中,「c」和「d」是否被切換?如果輸入列表超過輸入數字的兩倍,會發生什麼情況? –

+0

@DanielWagner這是非常錯誤的,對不起。就像mobyte指出的那樣,'foo'與'zip(partition(list,spacing))'是等價的,但也許它沒有名字。 – MaiaVictor

回答

3

您可以使用partition

(partition 3 '[a b c d e f]) 
=> ((a b c) (d e f)) 

(partition 2 '[a b c d e f]) 
=> ((a b) (c d) (e f)) 

編輯:

(apply map list (partition 3 '[a b c d e f])) 
=> ((a d) (b e) (c f)) 
+0

太棒了!謝謝。關於「foo」本身呢,它有一個名字嗎? – MaiaVictor

+0

@Dokkat新增。 – mobyte

+0

這是一個實現,而不是名稱,哈哈!我很欣賞這個好意,但請打勾。 – MaiaVictor

1

我不認爲這是對於一個內置的功能。實施起來很簡單,很好。

我知道你不想執行,但標籤中的一個是哈斯克爾所以也許你想看到這個

p :: Int -> [a] -> [[a]] 
p n xs = [ [x | (x ,y) <- ys , y `mod` n == i] | i <- [0 .. n - 1] , let ys = zip xs [0 .. ]] 

這是相當實用。

1

您的goo功能是drop與翻轉的參數。鑑於這種情況,你可以實現foo幾乎就像你在你的問題說:

let foo list spacing = zip list (drop spacing list) 

這仍然沒有確切地給你需要的,雖然結果,但接近:

Prelude> foo "abcdef" 3 
[('a','d'),('b','e'),('c','f')] 

編輯:

仔細閱讀,您的goo功能是splitAt與翻轉的參數。鑑於此,foo可以這樣定義:

let foo list spacing = (uncurry zip) $ splitAt spacing list 

這是相同的:

let foo list spacing = let (left, right) = splitAt spacing list 
         in zip left right 
+0

不錯!你是怎樣找到它的? – MaiaVictor

+0

我想我已經在LYAH書中讀到過它。它涵蓋了大部分這些:) – MisterMetaphor