# /wakamoleguy

## Advent of Code 2022 - Day 3 Bonus: Split in Half

While writing up the post for Advent of Code Day 3, I came across a small improvement to my `splitInHalf` function. This function takes a string and returns both parts of it. Here's the original:

``````splitInHalf :: String -> [String]
splitInHalf s = [take size s, drop size s]
where
size = length s `div` 2``````

Prelude (essentially Haskell's standard library) has a function `splitAt`, which we can use:

``````splitInHalf :: String -> [String]
splitInHalf s = [s1, s2]
where
(s1, s2) = splitAt (length s `div` 2)``````

Converting from the tuple to the list should be unnecessary. Let's try `chunksOf`?

``````splitInHalf :: String -> [String]
splitInHalf s = chunksOf (length s `div` 2) s``````

### Point Free?

We can convert the above function into a point-free style. Look at the form of our functions:

``````splitInHalf :: String -> [String]
halfLength :: String -> Int -- (`div` 2) . length
chunksOf :: Int -> String -> [String]``````
`(r ->)` is an instance of a monad, so let's factor `(String ->)` out from our types and see what's left. We replace each function `(String -> a)` with `m a`:
``````splitInHalf :: m [String]
halfLength :: m Int
chunksOf :: Int -> m [String]``````

So is there a function that can take our `halfLength` and `chunksOf` and returns our function `splitInHalf`? It would have the type of `m a -> (a -> m b) -> m b`. It does exist, it's called "bind" (`>>=`), and it's kinda the core functionaly of monads!

``````splitInHalf :: String -> [String]
splitInHalf = (`div` 2) . length >>= chunksOf``````

Using the flipped version of bind brings another new perspective:

``````splitInHalf :: String -> [String]
splitInHalf = chunksOf =<< (`div` 2) . length``````

This looks similar to our original, but composed of functions instead of values.

### Advent of Code 2022 Series

This post is part of a series describing my Haskell solutions to Advent of Code 2022.

Main Post: Day 3: Rucksack Reorganization

Cheers!