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\$
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 '14 at 13:41
  • \$\begingroup\$ You're right! I've added a case to handle negative n. \$\endgroup\$ May 5 '14 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 '14 at 11:06
  • \$\begingroup\$ Right again! The "don't care" placeholder should be used whenever possible. I've edited that in. \$\endgroup\$ May 5 '14 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.