2013-03-30 65 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