Let’s consider 2 lists: ["a","b","c"]
and ["a","b","c","d","e","f"]
I want to check if the first list is the beginning of the other list I thought I could use:
["a","b","c"] == head (splitAt (length ["a","b","c"]) ["a","b","c","d","e","f"])
Unfortunately this doesn't work. Is there another way to get the first the 3 first elements out of a list in a new list?
In Python lists are zero-indexed, so the first element is available at index 0 . Similarly, we can also use the slicing syntax [:1] to get the first element of a list in Python.
To access the first n elements from a list, we can use the slicing syntax [ ] by passing a 0:n as an arguments to it . 0 is the start index (it is inculded). n is end index (it is excluded).
There is a function in Haskell that takes first n elements of user-supplied list, named take . The syntax is: function-name arg1 arg2 . So, take takes first 1000 elements from an infinite list of numbers from 0 to infinity.
Rather than using take
, you could use zipWith
to avoid traversing the lists twice. When you call length
, you first have to traverse the shorter list, then you take that many values from the longer list, then you traverse the lists, comparing element by element. What would make more sense is to traverse both lists as the same time, stopping your comparison when the shorter one is expired. zipWith
provides exactly this functionality:
-- Definitions for `and` and `zipWith` in `Prelude`
--
-- and :: [Bool] -> Bool
-- and [] = True
-- and (x:xs) = x && and xs
--
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
-- zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
-- zipWith _ _ _ = []
sameStartingElements :: Eq a => [a] -> [a] -> Bool
sameStartingElements xs ys = and $ zipWith (==) xs ys
Thanks to laziness, this definition will only traverse both lists once, and it stops as soon as one of them runs out of elements. This will be somewhat more efficient, and it avoids having to know the length of either list.
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