# [ACCEPTED]-How to change the order of arguments?-haskell

If you feel like editing functions after 46 they're written, you really really should 45 read
Conal Elliott's excellent blog post 44 *semantic editor combinators*

http://conal.net/blog/posts/semantic-editor-combinators

In fact, everyone should read it anyway. It's 43 a genuinely useful
method (which I'm abusing 42 here). Conal uses more constructs than just 41 `result`

and `flip`

to very flexible effect.

```
result :: (b -> b') -> ((a -> b) -> (a -> b'))
result = (.)
```

Suppose I 40 have a function that uses 3 arguments

```
use3 :: Char -> Double -> Int -> String
use3 c d i = c: show (d^i)
```

and 39 I'd like to swap the first two, I'd just 38 use `flip use3`

as you say,
but if I wanted to swap 37 the seconnd and third, what I want is to 36 apply `flip`

to the result of applying `use3`

to its 35 first argument.

```
use3' :: Char -> Int -> Double -> String
use3' = (result) flip use3
```

Let's move along and swap 34 the fourth and fifth arguments of a function 33 `use5`

that uses 5.

```
use5 :: Char -> Double -> Int -> (Int,Char) -> String -> String
use5' :: Char -> Double -> Int -> String -> (Int,Char) -> String
use5 c d i (n,c') s = c : show (d ^ i) ++ replicate n c' ++ s
```

We need to apply `flip`

to the result 32 of applying `use5`

to it's first three arguments,
so 31 that's the result of the result of the result:

```
use5' = (result.result.result) flip use5
```

Why 30 not save thinking later and define

```
swap_1_2 :: (a1 -> a2 -> other) -> (a2 -> a1 -> other)
swap_2_3 :: (a1 -> a2 -> a3 -> other) -> (a1 -> a3 -> a2 -> other)
--skip a few type signatures and daydream about scrap-your-boilerplate and Template Haskell
swap_1_2 = flip
swap_2_3 = result flip
swap_3_4 = (result.result) flip
swap_4_5 = (result.result.result) flip
swap_5_6 = (result.result.result.result) flip
```

...and 29 that's where you should stop if you like 28 simplicity and elegance.
Note that the 27 type `other`

could be `b -> c -> d`

so because of fabulous Curry 26 and right associativity of `->`

,
swap_2_3 works 25 for a function which takes any number of 24 arguments above two.
For anything more complicated, you 23 should really write a permuted function 22 by hand.
What follows is just for the sake 21 of intellectual curiosity.

Now, what about 20 swapping the second and fourth arguments? [Aside: there's 19 a theorem I remember from my algebra lectures 18 that any permutation can be made as the 17 composition of swapping adjacent items.]

We 16 could do it like this:
step 1: move 2 next 15 to 4 (`swap_2_3`

)

```
a1 -> a2 -> a3 -> a4 -> otherstuff
a1 -> a3 -> a2 -> a4 -> otherstuff
```

swap them there using `swap_3_4`

```
a1 -> a3 -> a2 -> a4 -> otherstuff
a1 -> a3 -> a4 -> a2 -> otherstuff
```

then swap 4 14 back to position 2 using `swap_2_3`

again:

```
a1 -> a3 -> a4 -> a2 -> otherstuff
a1 -> a4 -> a3 -> a2 -> otherstuff
```

so

```
swap_2_4 = swap_2_3.swap_3_4.swap_2_3
```

Maybe 13 there's a more terse way of getting there 12 directly with lots of results and flips 11 but random messing didn't find it for me!

Similarly, to 10 swap 1 and 5 we can move 1 over to 4, swap 9 with 5, move 5 back from 4 to 1.

```
swap_1_5 = swap_1_2.swap_2_3.swap_3_4 . swap_4_5 . swap_3_4.swap_2_3.swap_1_2
```

Or if you 8 prefer you could reuse `swap_2_4`

by flipping at the 7 ends
(swapping 1 with 2 and 5 with 4), swap_2_4 6 then flipping at the ends again.

```
swap_1_5' = swap_1_2.swap_4_5. swap_2_4 .swap_4_5.swap_1_2
```

Of course 5 it's much easier to define

```
swap_1_5'' f a b c d e = f e b c d a
```

which has the 4 benefit of being clear, consise, efficient 3 and has a helpful type signature in ghci 2 without explicitly annotating it.

However, this 1 was a fantastically entertaining question, thanks.

The best way in general is to just do it 5 manually. Assume you have a function

```
f :: Arg1 -> Arg2 -> Arg3 -> Arg4 -> Res
```

and 4 you would like

```
g :: Arg4 -> Arg1 -> Arg3 -> Arg2 -> Res
```

then you write

```
g x4 x1 x3 x2 = f x1 x2 x3 x4
```

If you need 3 a particular permutation several times, then 2 you can of course abstract from it, like 1 `flip`

does for the two-argument case:

```
myflip :: (a4 -> a1 -> a3 -> a2 -> r) -> a1 -> a2 -> a3 -> a4 -> r
myflip f x4 x1 x3 x2 = f x1 x2 x3 x4
```

More Related questions

We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.