I was working on Haskell Problem 21:
Insert an element at a given position into a list.
Example:
* (insert-at 'alfa '(a b c d) 2) (A ALFA B C D)
I have two different solutions:
--Problem 21 (also not tail recursive)
insertAt :: a -> [a] -> Int -> [a]
insertAt v [] n = [v]
insertAt v arr 1 = (v:arr)
insertAt v (x:xs) n = (x:(insertAt v xs $ n - 1))
--Tail recursive version
insertAtB :: a -> [a] -> Int -> [a]
insertAtB v arr n = loop v n arr []
where loop v n [] acc = (myReverse acc) ++ [v]
loop v 1 arr acc = (myReverse acc) ++ [v] ++ arr
loop v n (x:xs) acc = loop v (n - 1) xs (x:acc)
Which is better stylistically? Which is better in terms of runtime and memory use?
How can you determine what order of arguments is the best for currying? Is it only based on your own usage or is there a better way to determine this?
insertAt item xs n = take n xs ++ [item] ++ drop n xs
\$\endgroup\$splitAt
would get both in one pass. \$\endgroup\$