I'm reading through Learn You a Haskell and reached a spot where I'm trying to move an element in a list to the head. I've come up with what I think is the naive way and I'm curious if someone can show me what the experienced Haskell programmer would do instead.
In this example, I have a list of Integers and I want to move the element '4', which would be index '3', to the head of the list.
let nums = [1, 2, 3, 4, 5]
(nums !! 3) : delete (nums !! 3) nums
returns [4, 1, 2, 3, 5].
What do you think?
I would do it this way:
move n as = head ts : (hs ++ tail ts)
where (hs, ts) = splitAt n as
splitAt
splits a list at the given position, it returns the two parts that are created by the splitting (here hs
and ts
). The element that should be moved to the front is now at the beginning of ts
. head ts
returns just this first element of ts
, tail ts
returns everything but that first element. The result of the function are just these parts combined in the right order: hs
concatenated with tail ts
and prepended by the element head ts
.
Experienced Haskellers hardly ever using list indexing. I'd use break to avoid repeated traversals (assuming you want to match on element '4', not index '3'):
case break (== 4) [1, 2, 3, 4, 5] of
(a,x:xs) -> x:a ++ xs
(a,xs) -> a ++ xs
As in:
Prelude Data.List> case break (== 4) [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
We can do the same with indexing via 'splitAt':
Prelude Data.List> case splitAt 3 [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With