2
\$\begingroup\$

Here's how I wrote the Haskell splitAt function:

splitAt' :: Int -> [a] -> ([a], [a])
splitAt' n ys 
      | n < 0     = ([], ys)
      | otherwise = splitAt'' n ys []
      where splitAt'' a (x:xs) acc
                  | a == 0 = (acc, x:xs)
                  | null xs = (acc ++ [x], [])
                  | otherwise = splitAt'' (a-1) xs (acc ++ [x])

I don't like I'm using the append (++) function to add an element to the end of my acc(umulator).

But, given the importance of ordering, I'm not sure how to avoid using it.

Please review this code as well.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You should be able to implement it without ++.

splitAt' :: Int -> [a] -> ([a], [a])
splitAt' 0 ys     = ([], ys)
splitAt' _ []     = ([], [])
splitAt' n (y:ys)
  | n < 0     = ([], (y:ys))
  | otherwise = ((y:a), b)
  where (a, b) = splitAt' (n - 1) ys
\$\endgroup\$
4
  • \$\begingroup\$ Hi @200_success. Re: negatives aren't allowed: *Main> splitAt (-3) "heyman" produces ("","heyman") using GHCI 7.6.3. Also, with your above function, using a negative won't produce an error. It'll simply put the entire list in the first part of the tuple, leaving [] for the second part. Example: *Main> splitAt' (-3) [1..100] produces ([1,...,100],[]) \$\endgroup\$ May 4, 2014 at 13:41
  • \$\begingroup\$ You're right! I've added a case to handle negative n. \$\endgroup\$ May 5, 2014 at 10:14
  • \$\begingroup\$ Thanks! Out of curiosity, when do you use the "don't care" (_) for arguments? Example: splitAt' n [] but n isn't used so why not use don't care? Maybe there's a general style rule? \$\endgroup\$ May 5, 2014 at 11:06
  • \$\begingroup\$ Right again! The "don't care" placeholder should be used whenever possible. I've edited that in. \$\endgroup\$ May 5, 2014 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.