## Rotating Args in Haskell and Ruby Block Style Programming

I was writing some Haskell code and came across a function whose arguments weren't in the order I wanted. With most languages you're stuck, the library writer made a choice and now you have to live with it. But Haskell gives you more options ...

You may have encountered this before, for example with `mapM_`

. The type signature of `mapM_`

is `mapM_ :: (Monad m) => (a -> m b) -> [a] -> m ()`

. But you can use flip on it and turn the type signature into `flip mapM_ :: (Monad m) => [a] -> (a -> m b) -> m ()`

which then lets you write code like this.

```
flip mapM_ [0..10] $ \n -> do
print n
print $ n * 3
```

Rubyists should see a familiar pattern there that looks a lot like a `do/end`

block.

```
(0..10).each do |n|
puts n
puts n * 3
end
```

This is so useful that there is another function already defined that acts like `mapM_`

with its arguments flipped. It's called `forM_`

and as you might have guessed, it's type signature is `forM_ :: (Monad m) => [a] -> (a -> m b) -> m ()`

.

```
forM_ [0..10] $ \n -> do
print n
print $ n * 3
```

The `flip`

function works very well for two argument functions, but what about three arguments or more? I was recently working with `zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()`

. To use it as is, you'd have to write code like this.

```
zipWithM_ (\a b -> do { print (a + b); print (a + b * 3) }) [0..10] [4..]
```

Blecch. Hey, I want my code block at the end so I can work with it like I would in Ruby. I can't use `flip`

here so what can I do? Enter in a new routine we'll call `frot`

, for function rotate.

```
frot2 = flip
frot3 f b c a = f a b c
```

So what can we do with `frot`

? Check out this little example.

```
-- frot2 works just like flip (obviously)
frot2 mapM_ [0..10] $ \n -> do
print n
print $ n * 3
-- original zipWithM_
ghci> :t zipWithM_
zipWithM_ :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m ()
-- We can alter zipWithM_ to act like it takes a block
ghci> :t frot3 zipWithM_
frot3 zipWithM_ :: (Monad m) => [a] -> [b] -> (a -> b -> m c) -> m ()
frot3 zipWithM_ [0..10] [4..] $ \a b -> do
print (a + b)
print (a + b * 3)
-- We can chain frot calls to alter the order - put [b] before [a]
ghci> :t frot2 $ frot3 zipWithM_
frot2 $ frot3 zipWithM_ :: (Monad m) => [b] -> [a] -> (a -> b -> m c) -> m ()
frot2 (frot3 zipWithM_) [4..] [0..10] $ \a b -> do
print (a + b)
print (a + b * 3)
-- We can continue rotating args
ghci> :t frot3 $ frot3 zipWithM_
frot3 $ frot3 zipWithM_ :: (Monad m) =>
[b] -> (a -> b -> m c) -> [a] -> m ()
frot3 (frot3 zipWithM_) [4..] (\a b -> do { print (a + b); print (a + b * 3)}) [0..10]
-- If we rotate enough, we're back where we started
ghci> :t frot3 $ frot3 $ frot3 zipWithM_
frot3 $ frot3 $ frot3 zipWithM_ :: (Monad m) =>
(a -> b -> m c) -> [a] -> [b] -> m ()
```

The best part about this is that `frot`

is not tied to `zipWithM_`

. It can be used with any function. For example, we can alter the `findWithDefault`

function from `Data.Map`

just as easily.

```
ghci> :t findWithDefault
findWithDefault :: (Ord k) => a -> k -> Map k a -> a
ghci> :t frot3 $ frot3 findWithDefault
frot3 $ frot3 findWithDefault :: (Ord k) => Map k a -> a -> k -> a
-- Now we can partially apply and use
> let ds = fromList [("new england", "patriots"), ("new york", "giants")]
> findTeam = frot3 (frot3 findWithDefault) ds "no team"
> findTeam "peoria"
"no team"
> findTeam "new york"
"giants"
```

**Update:** Fixed typo in `frot3`

.

**Update 2:** Part 2 partially explains why this works in Haskell. Obtaining a full understanding is left as an exercise for the reader.