\$\begingroup\$
\$\endgroup\$
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.
asked May 4, 2014 at 1:22
1 Answer 1
\$\begingroup\$
\$\endgroup\$
4
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
answered May 4, 2014 at 6:26
-
\$\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\$Kevin Meredith– Kevin Meredith2014年05月04日 13:41:36 +00:00Commented May 4, 2014 at 13:41 -
\$\begingroup\$ You're right! I've added a case to handle negative
n
. \$\endgroup\$200_success– 200_success2014年05月05日 10:14:53 +00:00Commented 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\$Kevin Meredith– Kevin Meredith2014年05月05日 11:06:52 +00:00Commented 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\$200_success– 200_success2014年05月05日 14:34:44 +00:00Commented May 5, 2014 at 14:34
lang-hs