I was wondering if there is a function that lets me split a list at the first occurrence of an element, excluding that element. Basically, suppose:
listT= [1,3,2,5,6,3,2,6]
then I want to define (or not, if it already exists), a function splitAtFirst so that
splitAtFirst 2 listT = [[1,3],[5,6,3,2,6]]
my attempt so far looks like this:
splitAtfirst::(Eq a)=> a->[a]->[[a]]
splitAtfirst _ []=[]
splitAtfirst a (x:xs)
|a==x = [xs]
|otherwise = [x]: splitAtfirst a (xs)
However, I get
>splitAtfirst 2 [1,3,2,5,6,3,2,6]
>[[1],[3],[5,6,3,2,6]]
I know why the problem happens, but so far I haven't been able to find a good solution
I appreciate any help!
Edit: this is an auxiliary function that only will be called after checking that elem is in the list, so dealing with the case when it does not exist it's not really necessary. I appreciate your help
Since dfeuer has already pointed the way towards fixing your implementation, I will just chime in with the ready-made solution:
splitAtFirst :: Eq a => a -> [a] -> ([a], [a])
splitAtFirst x = fmap (drop 1) . break (x ==)
This splitAtFirst
implements the second option from the three suggestions in dfeuer's answer. A few notes on each of the components:
(x ==)
is a function which tests for equality with x
, returning a Bool
.
break
uses a boolean test (here, (x ==)
) to break a list in two, the second list beginning with the first element that passes the test. The two lists are returned as a pair (see dfeuer's answer for the reason why it is so).
drop 1
drops the first element of a list if it is not empty (and leaves it alone if it is empty).
fmap
would take quite a bit longer to explain properly, so I will just say that fmap f
applied on a pair (such as the result of break
) applies the function f
to the second element of the pair. In our case, fmap (drop 1)
will remove the first element of the second list -- that is, the separator. (To find out more about fmap
, search for the keyword "functor", or just try using it on a list or a Maybe
-value and see what happens.)
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