将高阶函数从Python转换为Haskell

将高阶函数从Python转换为Haskell,python,haskell,higher-order-functions,Python,Haskell,Higher Order Functions,我有以下代码: import operator def stagger(l, w): if len(l)>=w: return [tuple(l[0:w])]+stagger(l[1:], w) return [] def pleat(f, l, w=2): return map(lambda p: f(*p), stagger(l, w)) if __name__=="__main__": print pleat(operator.a

我有以下代码:

import operator

def stagger(l, w):
    if len(l)>=w:
        return [tuple(l[0:w])]+stagger(l[1:], w)
    return []

def pleat(f, l, w=2):
    return map(lambda p: f(*p), stagger(l, w))

if __name__=="__main__":
    print pleat(operator.add, range(10))
    print pleat(lambda x, y, z: x*y/z, range(3, 13), 3)
    print pleat(lambda x: "~%s~"%(x), range(10), 1)
    print pleat(lambda a, b, x, y: a+b==x+y, [3, 2, 4, 1, 5, 0, 9, 9, 0], 4)
重要部分:Pleat接受任何函数和任何序列,并将该序列中的前几个元素作为参数传递到接收函数中


在Haskell或我在做梦吗?

下面的类型签名是可选的:

stagger :: [a] -> Int -> [[a]] stagger l w | length l >= w = take w l : stagger (tail l) w | otherwise = [] pleat :: ([a] -> b) -> [a] -> Int -> [b] pleat f l w = map f $ stagger l w main = do print $ pleat (\[x, y] -> x+y) [0..9] 2 print $ pleat (\[x, y, z] -> x*y/z) [3..12] 3 print $ pleat (\[x] -> "~" ++ show x ++ "~") [0..9] 1 print $ pleat (\[a, b, x, y] -> a+b == x+y) [3, 2, 4, 1, 5, 0, 9, 9, 0] 4 交错::[a]->Int->[[a]] 错开 |长度l>=w=取w l:交错(尾部l)w |否则=[] 褶裥::([a]->b)->[a]->Int->[b] 褶皱f l w=地图f$交错l w main=do 打印$pleat(\[x,y]->x+y)[0..9]2 打印$pleat(\[x,y,z]>x*y/z)[3..12]3 打印$pleat(\[x]->“~”++显示x++“~”)[0..9]1 打印$pleat(\[a,b,x,y]->a+b==x+y)[3,2,4,1,5,0,9,9,0]4
其思想是,函数明确表示将未知长度的列表作为参数,因此它不是非常类型安全的。但是它几乎是Python代码的一对一映射。

有没有一种编写它的方法,这样你就可以传入(+)而不是(\[x,y]->x+y)?@Legatou:没有。除了拼写不同:
lift2 f[x,y]=f x y
print$pleat(lift2(+))[0..9]2
。Haskell不做多变量函数(typeclass黑客会告诉你不是这样,但后来它变为“做得不好”)。没有它们,总有办法清楚地表达你的意思。我认为这个答案是正确的。。。虽然令人沮丧。我有点希望能够像我最终在这里所做的那样动态地评估参数计数:也许“动态”一词暗示Haskell不是这样做的?@Legatou虽然不完全相同,但该函数至少是Prelude.sum的一个子函数。所以你可以用(\[x,y]->x+y)代替和。。。