2

I have the following code:

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)

Important part: Pleat takes any function and any sequence and passes the first handful of elements from that sequence into the received function as parameters.

Is there a way to do this in Haskell or am I dreaming?

1 Answer 1

6

The type signatures below are optional:

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

The idea is that the function is explicit about taking a list of unknown length as an argument, so it is not very type-safe. But it is pretty much a 1-to-1 mapping of the Python code.

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a way to write it so you can pass in (+) instead of (\[x,y] -> x+y) ?
@Legatou: no. Except for spelling it differently: lift2 f [x,y] = f x y, print $ pleat (lift2 (+)) [0..9] 2. Haskell doesn't do polyvariadic functions (typeclass hackers will tell you otherwise, but then it changes to "doesn't do them well"). There is always a way to state clearly what you mean without them.
I accept this answer as valid... though depressing. I was kinda hoping I could dynamically assess the parameter count the way I eventually did here: ishpeck.com/4squirrel/pleat.html
Maybe the word 'dynamic' is a clue that Haskell doesn't do it that way?
@ Legatou Although it is not exactly the same, that function is atleast a subfunction of Prelude.sum. So you can substitute (\[x,y] -> x+y) for sum ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.