# 99 Haskell Problems

## Problem 17

(*) Split a list into two parts; the length of the first part is given.

Do not use any predefined predicates.

Example:

* (split '(a b c d e f g h i k) 3) ( (A B C) (D E F G H I K))

Example in Haskell:

*Main> split "abcdefghik" 3 ("abc", "defghik")

Solution:

split :: [a] -> Int -> ([a],[a]) split [] _ = ([], []) split xs n = (fstPart xs n, sndPart xs n) fstPart [] _ = [] fstPart (x:xs) n | n == 0 = [] | otherwise = x:(fstPart xs (n-1)) sndPart [] _ = [] sndPart (x:xs) n | n == 0 = (x:xs) | otherwise = sndPart xs (n-1)

The fstPart basically does exactly what take does. The sndPart basically does exactly what drop does. Looking at the solution, we can use where to simplify this greatly:

split :: [a] -> Int -> ([a],[a]) split [] _ = ([], []) split (x:xs) n | n > 0 = (x:ys, zs) | otherwise = ([], x:xs) where (ys, zs) = split xs (n-1)

The where clause in this case relates (ys, zs) to xs and eliminate the need to define them separately.