Generalized partial application (again)

Please correct me if I'm wrong in any of the reasoning below. Haskell provides the ability the perform partial application on the rightmost arguments. I learned from some pretty smart guys that partial application cannot be emulated with lambas, because they behave differently operationally, e.g. e = trace "e" op = (+) a1 = let f = (op (e 1)) in (f 10, f 100) a2 = let f = (\x -> op (e 1) x) in (f 10, f 100) a1 and a2 are operationally not the same: a1 will evaluate (e 1) once, a2 will evaluate it twice. However, Haskell also allows to partially apply the second argument of binary functions (using sections) b1 = let f = (`op` (e 1)) in (f 10, f 100) b2 = let f = (\x -> (e 1) `op` x) in (f 10, f 100) Again, b1 evaluates (e 1) once, b2 twice. b1 is actually the same as c1 = let f = ((flip op) (e 1)) in (f 10, f 100) So for ternary functions we could write more permutations of flip: flip3_12 f a1 a2 a3 = f a2 a1 a3 flip3_13 f a1 a2 a3 = f a3 a2 a1 flip3_23 f a1 a2 a3 = f a1 a3 a2 And use these to partially apply any argument e1 x = trace "e1" x e2 x = trace "e2" x op2 :: Int -> Int -> Int -> Int op2 x y z = x+10*y+100*z z1 = let f = (flip3_12 op2) (e1 1) (e2 2) in (f 3, f 4) z2 = let f = (flip3_13 op2) (e1 1) (e2 2) in (f 3, f 4) z3 = let f = (flip3_23 op2) (e1 1) (e2 2) in (f 3, f 4) This could be extended to N-ary functions. Haskell doesn't give any special syntactic support for this, but it surely is possible. Am I missing something here? Is there any easier way to perform "generalized partial application"?

How about using "let"s?
2009/1/12 Peter Verswyvelen
e = trace "e" op = (+) a1 = let f = (op (e 1)) in (f 10, f 100) a2 = let f = (\x -> op (e 1) x) in (f 10, f 100) a1 and a2 are operationally not the same: a1 will evaluate (e 1) once, a2
a3 = let f = (let y = e 1 in (\x -> op y x)) in (f 10, f 100)
e1 x = trace "e1" x e2 x = trace "e2" x op2 :: Int -> Int -> Int -> Int op2 x y z = x+10*y+100*z z1 = let f = (flip3_12 op2) (e1 1) (e2 2) in (f 3, f 4) z2 = let f = (flip3_13 op2) (e1 1) (e2 2) in (f 3, f 4) z3 = let f = (flip3_23 op2) (e1 1) (e2 2) in (f 3, f 4)
z1' = let f = (let y1 = e1 1; y2 = e2 2 in (\x -> op2 y2 y1 x)) in (f 3, f 4) -- Felipe.
participants (2)
-
Felipe Lessa
-
Peter Verswyvelen